Пример #1
0
void DviSessionUpnp::ParseRequestUri(const Brx& aUrlTail, DviDevice** aDevice, DviService** aService)
{
    Parser parser(iReaderRequest->Uri());
    Brn tmp = parser.Next('/');
    if (tmp.Bytes() > 0) {
        Error(HttpStatus::kPreconditionFailed);
    }
    Brn udn = parser.Next('/');
    DviDevice* device = DviDeviceMap::Find(udn);
    *aDevice = device;
    if (device == NULL) {
        Error(HttpStatus::kPreconditionFailed);
    }
    Brn serviceName = parser.Next('/');
    if (parser.Remaining() != aUrlTail) {
        Error(HttpStatus::kPreconditionFailed);
    }
    const TUint count = device->ServiceCount();
    for (TUint i=0; i<count; i++) {
        DviService& service = device->Service(i);
        if (service.ServiceType().PathUpnp() == serviceName) {
            *aService = &service;
            break;
        }
    }
}
Пример #2
0
void DviSessionUpnp::Subscribe()
{
    LOG(kDvEvent, "Subscription request from ");
    iHeaderCallback.Log();
    LOG(kDvEvent, "\n");
    if (iHeaderSid.Received()) {
        Renew();
        return;
    }

    if (!iHeaderCallback.Received() || !iHeaderNt.Received() || !iHeaderTimeout.Received()) {
        Error(HttpStatus::kPreconditionFailed);
    }
    DviDevice* device;
    DviService* service;
    ParseRequestUri(DviProtocolUpnp::kEventUrlTail, &device, &service);
    if (device == NULL || service == NULL) {
        Error(HttpStatus::kPreconditionFailed);
    }
    TUint duration = iHeaderTimeout.Timeout();
    Brh sid;
    device->CreateSid(sid);
    SubscriptionDataUpnp* data = new SubscriptionDataUpnp(iHeaderCallback.Endpoint(), iHeaderCallback.Uri());
    DviSubscription* subscription = new DviSubscription(*device, *iPropertyWriterFactory, data, sid, duration);
    iPropertyWriterFactory->SubscriptionAdded(*subscription);
    DviSubscriptionManager::AddSubscription(*subscription);

    if (iHeaderExpect.Continue()) {
        iWriterResponse->WriteStatus(HttpStatus::kContinue, Http::eHttp11);
        iWriterResponse->WriteFlush();
    }
    // respond to subscription request
    iResponseStarted = true;
    iWriterResponse->WriteStatus(HttpStatus::kOk, Http::eHttp11);
    WriteServerHeader(*iWriterResponse);
    IWriterAscii& writerSid = iWriterResponse->WriteHeaderField(HeaderSid::kHeaderSid);
    writerSid.Write(HeaderSid::kFieldSidPrefix);
    writerSid.Write(subscription->Sid());
    writerSid.WriteFlush();
    IWriterAscii& writerTimeout = iWriterResponse->WriteHeaderField(HeaderTimeout::kHeaderTimeout);
    writerTimeout.Write(HeaderTimeout::kFieldTimeoutPrefix);
    writerTimeout.WriteUint(duration);
    writerTimeout.WriteFlush();
    iWriterResponse->WriteHeader(Http::kHeaderConnection, Http::kConnectionClose);
    iWriterResponse->WriteFlush();
    iResponseEnded = true;

    LOG(kDvEvent, "Subscription complete for ");
    iHeaderCallback.Log();
    LOG(kDvEvent, ", sid is ");
    LOG(kDvEvent, subscription->Sid());
    LOG(kDvEvent, "\n");

    // Start subscription, prompting delivery of the first update (covering all state variables)
    service->AddSubscription(subscription);
}
Пример #3
0
DviProtocolUpnpAdapterSpecificData* DviProtocolUpnp::AddInterface(const NetworkAdapter& aAdapter)
{
    TIpAddress addr = aAdapter.Address();
    Bws<Uri::kMaxUriBytes> uriBase;
    TUint port = iServer->Port(addr);
    DviDevice* root = (iDevice.IsRoot()? &iDevice : iDevice.Root());
    root->GetUriBase(uriBase, addr, port, *this);
    DviProtocolUpnpAdapterSpecificData* adapter = new DviProtocolUpnpAdapterSpecificData(iDvStack, *this, aAdapter, uriBase, port);
    iAdapters.push_back(adapter);
    return adapter;
}
Пример #4
0
void SuiteAlive::Test()
{
    Environment& env = iDvStack.Env();
    Blocker* blocker = new Blocker(env);
    CpListenerBasic* listener = new CpListenerBasic;
    NetworkAdapter* nif = env.NetworkAdapterList().CurrentAdapter(kAdapterCookie);
    SsdpListenerMulticast* listenerMulticast = new SsdpListenerMulticast(env, nif->Address());
    nif->RemoveRef(kAdapterCookie);
    TInt listenerId = listenerMulticast->AddNotifyHandler(listener);
    listenerMulticast->Start();
    DviDevice* device = new DviDeviceStandard(iDvStack, gNameDevice1);
    device->SetAttribute("Upnp.Domain", "a.b.c");
    device->SetAttribute("Upnp.Type", "type1");
    device->SetAttribute("Upnp.Version", "1");
    AddService(device, new DviService(iDvStack, "a.b.c", "service1", 1));
    AddService(device, new DviService(iDvStack, "a.b.c", "service2", 1));
    device->SetEnabled();
    blocker->Wait(1);
    /* we expect 5 messages but linux sometimes reports multicast messages from
      all subnets to listeners on any single subnet so just check that we've
      received a multiple of 5 messages */

    TEST(listener->TotalAlives() > 0);
    TEST(listener->TotalAlives() == listener->TotalByeByes());
    TEST(listener->TotalAlives() % 5 == 0);

    TUint byebyes = listener->TotalByeByes();
    Functor disabled = MakeFunctor(*this, &SuiteAlive::Disabled);
    device->SetDisabled(disabled);
    iSem.Wait();
    blocker->Wait(1); /* semaphore being signalled implies that the device has been
                         disabled.  We may require some extra time to receive the
                         multicast byebye confirming this */
    TEST(listener->TotalByeByes() > byebyes);
    TEST(listener->TotalByeByes() % 5 == 0);

    TUint alives = listener->TotalAlives();
    byebyes = listener->TotalByeByes();
    device->SetEnabled();
    blocker->Wait(1);
    TEST(listener->TotalAlives() > alives);
    TEST(listener->TotalAlives() - alives == listener->TotalByeByes() - byebyes);
    TEST(listener->TotalAlives() % 5 == 0);

    // Control point doesn't process ssdp:update notifications
    // check that updates are basically working by counting the extra alive messages instead
    alives = listener->TotalAlives();
    device->SetAttribute("Upnp.TestUpdate", "1");
    blocker->Wait(1);
    TEST(listener->TotalAlives() > alives);
    TEST(listener->TotalAlives() % 5 == 0);

    device->Destroy();
    listenerMulticast->RemoveNotifyHandler(listenerId);
    delete listenerMulticast;
    delete listener;
    delete blocker;
}
Пример #5
0
DvProvider::DvProvider(DviDevice& aDevice, const TChar* aDomain, const TChar* aType, TUint aVersion)
    : iDelayPropertyUpdates(false)
    , iPropertyChanged(false)
{
    iService = new DviService(aDomain, aType, aVersion);
    aDevice.AddService(iService); // ownership of service passed to aDevice
}
Пример #6
0
void DviDeviceMap::Add(DviDevice& aDevice)
{
    DviDeviceMap& self = DviStack::DeviceMap();
    self.iLock.Wait();
    Brn udn(aDevice.Udn());
    self.iMap.insert(std::pair<Brn,DviDevice*>(udn, &aDevice));
    self.iLock.Signal();
}
Пример #7
0
void DviDeviceMap::WriteResource(const Brx& aUriTail, TIpAddress aInterface, std::vector<char*>& aLanguageList, IResourceWriter& aResourceWriter)
{
    iLock.Wait();
    Parser parser(aUriTail);
    (void)parser.Next('/'); // skip leading slash
    Brn dir = parser.Next('/');
    if (dir.Bytes() > 0) {
        Map::iterator it = iMap.find(dir);
        if (it != iMap.end()) {
            DviDevice* device = it->second;
            iLock.Signal();
            device->WriteResource(parser.Remaining(), aInterface, aLanguageList, aResourceWriter);
            return;
        }
    }
    iLock.Signal();
}
Пример #8
0
void DviProtocolUpnp::Enable()
{
    iLock.Wait();
    
    // check we have at least the basic attributes requried for advertisement
    ASSERT(Domain().Bytes() > 0);
    ASSERT(Type().Bytes() > 0);
    ASSERT(Version() > 0);
    
    for (TUint i=0; i<iAdapters.size(); i++) {
        DviProtocolUpnpAdapterSpecificData* adapter = iAdapters[i];
        Bws<Uri::kMaxUriBytes> uriBase;
        DviDevice* root = (iDevice.IsRoot()? &iDevice : iDevice.Root());
        adapter->UpdateServerPort(*iServer);
        root->GetUriBase(uriBase, adapter->Interface(), adapter->ServerPort(), *this);
        adapter->UpdateUriBase(uriBase);
        adapter->ClearDeviceXml();
        if (iDevice.ResourceManager() != NULL) {
            const TChar* name = 0;
            GetAttribute("FriendlyName", &name);
            adapter->BonjourRegister(name, iDevice.Udn(), kProtocolName, iDevice.kResourceDir);
            /*GetAttribute("MdnsHostName", &name);
            if (name != NULL) {
                iDvStack.MdnsProvider()->MdnsSetHostName(name);
                Bwh redirectedPath(iDevice.Udn().Bytes() + kProtocolName.Bytes() + iDevice.kResourceDir.Bytes() + 4);
                redirectedPath.Append('/');
                Uri::Escape(redirectedPath, iDevice.Udn());
                redirectedPath.Append('/');
                redirectedPath.Append(kProtocolName);
                redirectedPath.Append('/');
                redirectedPath.Append(iDevice.kResourceDir);
                redirectedPath.Append('/');
                iDvStack.ServerUpnp().Redirect(Brn("/"), redirectedPath);
            }*/
        }
    }
    for (TUint i=0; i<iAdapters.size(); i++) {
        iAdapters[i]->SendByeByeThenAlive(*this);
    }
    iLock.Signal();
    QueueAliveTimer();
}
Пример #9
0
void DviDeviceMap::Remove(DviDevice& aDevice)
{
    DviDeviceMap& self = DviStack::DeviceMap();
    self.iLock.Wait();
    Brn udn(aDevice.Udn());
    Map::iterator it = self.iMap.find(udn);
    if (it != self.iMap.end()) {
        self.iMap.erase(it);
    }
    self.iLock.Signal();
}
void DviProviderSubscriptionLongPoll::Subscribe(IDvInvocation& aInvocation, const Brx& aClientId, const Brx& aUdn, const Brx& aService, TUint aRequestedDuration,
                                                IDvInvocationResponseString& aSid, IDvInvocationResponseUint& aDuration)
{
    if (aRequestedDuration > kTimeoutLongPollSecs) {
        aRequestedDuration = kTimeoutLongPollSecs;
    }

    DviDevice* device = iDvStack.DeviceMap().Find(aUdn);
    if (device == NULL) {
        aInvocation.Error(kErrorCodeBadDevice, kErrorDescBadDevice);
    }
    DviService* service = NULL;
    const TUint serviceCount = device->ServiceCount();
    for (TUint i=0; i<serviceCount; i++) {
        DviService* s = &device->Service(i);
        if (s->ServiceType().PathUpnp() == aService) {
            service = s;
            break;
        }
    }
    if (service == NULL) {
        aInvocation.Error(kErrorCodeBadService, kErrorDescBadService);
    }
    Brh sid;
    device->CreateSid(sid);
    TUint timeout = aRequestedDuration;
    DviSubscription* subscription = new DviSubscription(iDvStack, *device, iPropertyUpdateCollection, NULL, sid, timeout);

    aInvocation.StartResponse();
    aSid.Write(subscription->Sid());
    aSid.WriteFlush();
    aDuration.Write(timeout);
    aInvocation.EndResponse();

    // Start subscription, prompting availability of the first update (covering all state variables)
    iPropertyUpdateCollection.AddSubscription(aClientId, subscription);
    iDvStack.SubscriptionManager().AddSubscription(*subscription);
    service->AddSubscription(subscription);
}
Пример #11
0
DviProtocolUpnp::DviProtocolUpnp(DviDevice& aDevice)
    : iDevice(aDevice)
    , iDvStack(aDevice.GetDvStack())
    , iLock("DMUP")
    , iUpdateCount(0)
    , iSuppressScheduledEvents(false)
{
    SetAttribute(kAttributeKeyVersionMajor, "1");
    SetAttribute(kAttributeKeyVersionMinor, "1");
    iLock.Wait();
    iServer = &(iDvStack.ServerUpnp());
    NetworkAdapterList& adapterList = iDvStack.Env().NetworkAdapterList();
    Functor functor = MakeFunctor(*this, &DviProtocolUpnp::HandleInterfaceChange);
    iCurrentAdapterChangeListenerId = adapterList.AddCurrentChangeListener(functor);
    iSubnetListChangeListenerId = adapterList.AddSubnetListChangeListener(functor);
    std::vector<NetworkAdapter*>* subnetList = adapterList.CreateSubnetList();
    AutoNetworkAdapterRef ref(iDvStack.Env(), "DviProtocolUpnp ctor");
    const NetworkAdapter* current = ref.Adapter();
    if (current != NULL) {
        AddInterface(*current);
    }
    else {
        for (TUint i=0; i<subnetList->size(); i++) {
            NetworkAdapter* subnet = (*subnetList)[i];
            try {
                AddInterface(*subnet);
            }
            catch (NetworkError& ) {
                // some hosts may have adapters that don't support multicast
                // we can't differentiate between no support ever and transient failure
                // (typical on Windows & Mac after hibernation) so just ignore this exception
                // and trust that we'll get advertised on another interface.
                char* adapterName = subnet->FullName();
                LOG2(kTrace, kError, "DvDevice unable to use adapter %s\n", adapterName);
                delete adapterName;
            }
        }
    }
    NetworkAdapterList::DestroySubnetList(subnetList);
    iAliveTimer = new Timer(iDvStack.Env(), MakeFunctor(*this, &DviProtocolUpnp::SendAliveNotifications), "DviProtocolUpnp");
    iLock.Signal();
}
DviProviderSubscriptionLongPoll::DviProviderSubscriptionLongPoll(DviDevice& aDevice)
    : DvProviderOpenhomeOrgSubscriptionLongPoll1(aDevice)
    , iDvStack(aDevice.GetDvStack())
    , iPropertyUpdateCollection(iDvStack.PropertyUpdateCollection())
    , iLock("LPMX")
    , iShutdown("LPSH", 0)
    , iExit(false)
    , iClientCount(0)
{
    EnableActionSubscribe();
    EnableActionUnsubscribe();
    EnableActionRenew();
    EnableActionGetPropertyUpdates();

    iShutdown.Signal();
    iMaxClientCount = iDvStack.Env().InitParams()->DvNumServerThreads() / 2;
    ASSERT(iMaxClientCount > 0);
    UpdateReadySignal empty;
    for (TUint i=0; i<iMaxClientCount; i++) {
        iUpdateReady.push_back(empty);
    }
}
Пример #13
0
void SuiteMsearch::Test()
{
    DviDevice* device = new DviDeviceStandard(iDvStack, gNameDevice1);
    iDevices[0] = device;
    device->SetAttribute("Upnp.Domain", "upnp.org");
    device->SetAttribute("Upnp.Type", "test1");
    device->SetAttribute("Upnp.Version", "1");
    AddService(device, new DviService(iDvStack, "upnp.org", "service1", 1));
    AddService(device, new DviService(iDvStack, "openhome.org", "service2", 3));
    AddService(device, new DviService(iDvStack, "upnp.org", "service3", 1));
    DviService* service = new DviService(iDvStack, "upnp.org", "service1", 1);
    TEST_THROWS(device->AddService(service), AssertionFailed);
    service->RemoveRef();
    device->SetEnabled();
    service = new DviService(iDvStack, "upnp.org", "service4", 1);
    TEST_THROWS(device->AddService(service), AssertionFailed);
    service->RemoveRef();

    device = new DviDeviceStandard(iDvStack, gNameDevice2);
    iDevices[1] = device;
    device->SetAttribute("Upnp.Domain", "openhome.org");
    device->SetAttribute("Upnp.Type", "test2");
    device->SetAttribute("Upnp.Version", "2");
    AddService(device, new DviService(iDvStack, "openhome.org", "service4", 2));
    AddService(device, new DviService(iDvStack, "openhome.org", "service5", 1));

    device = new DviDeviceStandard(iDvStack, gNameDevice2Embedded1);
    iDevices[1]->AddDevice(device);
    device->SetAttribute("Upnp.Domain", "openhome.org");
    device->SetAttribute("Upnp.Type", "test3");
    device->SetAttribute("Upnp.Version", "1");
    AddService(device, new DviService(iDvStack, "upnp.org", "service1", 1));
    AddService(device, new DviService(iDvStack, "openhome.org", "service6", 1));
    AddService(device, new DviService(iDvStack, "openhome.org", "service2", 3));
    service = new DviService(iDvStack, "openhome.org", "service5", 1);
    TEST_THROWS(device->AddService(service), AssertionFailed);
    service->RemoveRef();
    iDevices[1]->SetEnabled();
    device->SetEnabled();
    device = new DviDeviceStandard(iDvStack, kNameDummy);
    TEST_THROWS(iDevices[1]->AddDevice(device), AssertionFailed);
    device->Destroy();
    //Wait(); // allow time for initial annoucements to be delivered

    TestMsearchAll();
    TestMsearchRoot();
    TestMsearchUuid();
    TestMsearchDeviceType();
    TestMsearchServiceType();
}
Пример #14
0
TBool DviSessionLpec::SubscriptionData::Matches(DviDevice& aDevice, DviService& aService) const
{
    return (iDevice->Udn() == aDevice.Udn() && iService->ServiceType().FullName() == aService.ServiceType().FullName());
}
Пример #15
0
void    mdvi_shrink_glyph_grey(DviContext *dvi, DviFont *font,
    DviFontChar *pk, DviGlyph *dest)
{
    int    rows_left, rows;
    int    cols_left, cols, init_cols;
    long    sampleval, samplemax;
    BmUnit    *old_ptr;
    void    *image;
    int    w, h;
    int    x, y;
    DviGlyph *glyph;
    BITMAP     *map;
    Ulong    *pixels;
    int    npixels;
    Ulong    colortab[2];
    int    hs, vs;
    DviDevice *dev;

    hs = dvi->params.hshrink;
    vs = dvi->params.vshrink;
    dev = &dvi->device;
    
    glyph = &pk->glyph;
    map = (BITMAP *)glyph->data;
    
    x = (int)glyph->x / hs;
    init_cols = (int)glyph->x - x * hs;
    if(init_cols <= 0)
        init_cols += hs;
    else
        x++;
    w = x + ROUND((int)glyph->w - glyph->x, hs);

    cols = (int)glyph->y + 1;
    y = cols / vs;
    rows = cols - y * vs;
    if(rows <= 0) {
        rows += vs;
        y--;
    }
    h = y + ROUND((int)glyph->h - cols, vs) + 1;
    ASSERT(w && h);
    
    /* before touching anything, do this */
    image = dev->create_image(dev->device_data, w, h, BITMAP_BITS);
    if(image == NULL) {
        mdvi_shrink_glyph(dvi, font, pk, dest);
        return;
    }
    
    /* save these colors */
    pk->fg = MDVI_CURRFG(dvi);
    pk->bg = MDVI_CURRBG(dvi);
    
    samplemax = vs * hs;
    npixels = samplemax + 1;
    pixels = get_color_table(&dvi->device, npixels, pk->fg, pk->bg,
            dvi->params.gamma, dvi->params.density);
    if(pixels == NULL) {
        npixels = 2;
        colortab[0] = pk->fg;
        colortab[1] = pk->bg;
        pixels = &colortab[0];
    }
    
    /* setup the new glyph */
    dest->data = image;
    dest->x = x;
    dest->y = glyph->y / vs;
    dest->w = w;
    dest->h = h;

    y = 0;
    old_ptr = map->data;
    rows_left = glyph->h;

    while(rows_left && y < h) {
        x = 0;
        if(rows > rows_left)
            rows = rows_left;
        cols_left = glyph->w;
        cols = init_cols;
        while(cols_left && x < w) {
            if(cols > cols_left)
                cols = cols_left;
            sampleval = do_sample(old_ptr, map->stride,
                glyph->w - cols_left, cols, rows);
            /* scale the sample value by the number of grey levels */
            if(npixels - 1 != samplemax)
                sampleval = ((npixels-1) * sampleval) / samplemax;
            ASSERT(sampleval < npixels);
            dev->put_pixel(image, x, y, pixels[sampleval]);
            cols_left -= cols;
            cols = hs;
            x++;
        }
        for(; x < w; x++)
            dev->put_pixel(image, x, y, pixels[0]);
        old_ptr = bm_offset(old_ptr, rows * map->stride);
        rows_left -= rows;
        rows = vs;
        y++;
    }
    
    for(; y < h; y++) {
        for(x = 0; x < w; x++)
            dev->put_pixel(image, x, y, pixels[0]);
    }

        dev->image_done(image);
    DEBUG((DBG_BITMAPS, "shrink_glyph_grey: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n",
        glyph->w, glyph->h, glyph->x, glyph->y,
        dest->w, dest->h, dest->x, dest->y));
}