Code Monkey home page Code Monkey logo

cocoaupnp's Issues

Can't discovery UPnP devices connected to iPhone's personal hotspot.

Hello.

I found this issue to previous release but it is still remained so I thought to need to notify it.

Before reading, I'm not good at English. Therefore, although my wording is some strange, please understand.

The issue is occurred as following situation :

  1. Turn on "Personal hotspot" in iPhone.
  2. Connect UPnP Root device to iPhone's hotspot.
  3. Start demo app in iPhone.
  4. Can't see any UPnP device at tableView. (NOT discovered)

I think it is because of the problem that interface name of personal hotspot is bridge, not en.

Original Code

if( (ifa->ifa_addr->sa_family == AF_INET) && !(ifa->ifa_flags & IFF_LOOPBACK) && !strncmp(ifa->ifa_name, "en", 2)) {
    NSData *data = [NSData dataWithBytes:ifa->ifa_addr length:sizeof(struct sockaddr_in)];
    NSString *if_name = [NSString stringWithUTF8String:ifa->ifa_name];
    [addresses setObject:data forKey:if_name];
}

So, I ask to modify the method availableNetworkInterfaces of SSDPServiceBrowser for all network environment. For example :

Modified Code

if (((ifa->ifa_addr->sa_family == AF_INET) || (ifa->ifa_addr->sa_family == AF_INET6)) && !(ifa->ifa_flags & IFF_LOOPBACK)) {
    if (!strncmp(ifa->ifa_name, "en", 2) || !strncmp(ifa->ifa_name, "bridge", 6)) {
        NSData *data = [NSData dataWithBytes:ifa->ifa_addr length:sizeof(struct sockaddr_in)];
        NSString *if_name = [NSString stringWithUTF8String:ifa->ifa_name];
                
        int addressFamily = [[GCDAsyncUdpSocket class] familyFromAddress:data];
        if (addressFamily != AF_UNSPEC) {
            [addresses setObject:data forKey:if_name];
        }
    }
}

cf) The method GCDWebServerGetPrimaryIPAddress in GCDWebServerFunctions of GCDWebServer has to be modified to subscribe event.

Also, there is another issue only in iOS 10. It is phone and devices are not in same network(only bridge).

I don't know why it is occurred only in iOS 10, but anyway it seems phone and device get different addresses in bridge network.

This issue was solved by modifying setupMulticastSocket.

Original Code

if (![self.multicastSocket joinMulticastGroup:SSDPMulticastGroupAddress error:&err]) {
    [self _notifyDelegateWithError:err];
    return;
}

Modified Code

if (![self.multicastSocket joinMulticastGroup:SSDPMulticastGroupAddress onInterface:[[GCDAsyncUdpSocket class] hostFromAddress:sourceAddress] error:&err]) {
    [self _notifyDelegateWithError:err];
    return;
}

Oh, Sorry it was too long to read. :-)

I always appreciate and respect your effort. Thank you.

MediaRendererDevice with empty services

Hi,

I'm having trouble understanding how the parsing is working. When I try and detect my STB (or CPE or whatever the name is) here is what I receive :
capture d ecran 2016-09-29 a 15 10 42
As you can see, ControlService, ManagerService & avTransportService are all empty. Any idea why ?

Add a convenience method for populating a media item

Best practice dictates that you only fetch required properties, to keep memory low. As an aside to this, there should be a method to quickly fetch all properties at a later stage:

- (void)updateMediaItem:(UPPMediaItem **)mediaItem
{
    [self browseWithObjectID:mediaItem.objectId
                 browseFlag:BrowseMetadata
                     filter:@"*"
              startingIndex:nil
             requestedCount:nil
               sortCriteria:nil
                 completion:completion];
}

How to create a normal UPnP server

I am having in trouble with create a UPnP Server, but I don't know where to start.

I see in the library there are classed: UPPEventServer.h, UPPMediaServerDevice.h but I don't think they are correct class of UPnP instance. Can you hep me?

How to Broadcasting iPhone's media as the service side

The current demo project works as a client side, it get media from other devices are broadcating. Now I want to setup a server side for broadcasting iphone's media, so other devices can connect and browsing this content.

LG Tvs : 714 - Illegal MIME-type

Hello,

First thanks for this very usefull library.
Everything works fine for me except for LG tv when I try to read a video.

When I go on the TV and launch the file explorer I can read all of the movies shared by my media server. (Without my app)

But when from my app I try to read a movie I have always the same errors : 714 - Illegal MIME-type or sometimes 704 - Format not supported for playback

This is only on this TV,
I do the same thing on other TVs and that works great.

Maybe I do not write the correct code, for example I don't write the currentURIMetaData?

Thanks in advance for your help.

This is my code:

            TV.avTransportService()?.setAVTransportURI(url, currentURIMetaData: "", instanceID: "0", success: { (ok, err) in
                if let error = err {
                    print("Soucis de set URI",error)
                    completion(false)

                }else{
                    print("URI SET OK")
                    TV.avTransportService()?.play(withInstanceID: "0", success: { (success, error2) in
                        if let error2 = error2 {
                            print("Soucis de lecture",error2)
                            completion(false)
                           
                        }else{
                            print("lecture OK en cours")
                            if success == true{
                                completion(true)
                            }else{
                                completion(false)
                            }
                        }
                        
                        
                    })
                    
                }
            })

Create Rendering Service Class

Rendering Service 1

http://upnp.org/specs/av/UPnP-av-RenderingControl-v1-Service.pdf

TODO:

  • 2.4.1. ListPresets
  • 2.4.2. SelectPreset
  • 2.4.3. GetBrightness
  • 2.4.4. SetBrightness
  • 2.4.5. GetContrast
  • 2.4.6. SetContrast
  • 2.4.7. GetSharpness
  • 2.4.8. SetSharpness
  • 2.4.9. GetRedVideoGain
  • 2.4.10. SetRedVideoGain
  • 2.4.11. GetGreenVideoGain
  • 2.4.12. SetGreenVideoGain
  • 2.4.13. GetBlueVideoGain
  • 2.4.14. SetBlueVideoGain
  • 2.4.15. GetRedVideoBlackLevel
  • 2.4.16. SetRedVideoBlackLevel
  • 2.4.17. GetGreenVideoBlackLevel
  • 2.4.18. SetGreenVideoBlackLevel
  • 2.4.19. GetBlueVideoBlackLevel
  • 2.4.20. SetBlueVideoBlackLevel
  • 2.4.21. GetColorTemperature
  • 2.4.22. SetColorTemperature
  • 2.4.23. GetHorizontalKeystone
  • 2.4.24. SetHorizontalKeystone
  • 2.4.25. GetVerticalKeystone
  • 2.4.26. SetVerticalKeystone
  • 2.4.27. GetMute
  • 2.4.28. SetMute
  • 2.4.29. GetVolume
  • 2.4.30. SetVolume
  • 2.4.31. GetVolumeDB
  • 2.4.32. SetVolumeDB
  • 2.4.33. GetVolumeDBRange
  • 2.4.34. GetLoudness
  • 2.4.35. SetLoudness
  • 2.4.36. Relationships Between Actions
  • 2.4.37. Common Error Codes

Please add an option to ignore the `NOTIFY` messages on delegate 'discovery:didFindDevice:'

Hi, we're working with your example.
When we change the service in timerFired: to a specific one instead of "ssdp:all", still devices with other types are shown.

- (void)timerFired:(NSTimer *)timer
{
    [[UPPDiscovery sharedInstance] startBrowsingForServices:@"urn:schemas-upnp-org:device:MediaServer:1"];
}

According to the docu of discovery:didFindDevice: devices are also reported when sending the Notify message:

Inform class that a new UPnP device was found: either through responding to an
M-SEARCH request or from periodic NOTIFY messaging to the multicast address.

Since we're searching for a specific URN, it's inconvenient to also receive detected devices that don't match this URN.
Would it be possible to add a property or parameter to ignore devices from the notify message?

Basic Device Parser Class

There should be a class able to parse a basic device into a usable object.

<-- © 2002 Contributing Members of the UPnP™ Forum. All Rights Reserved. -->
<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
  <specVersion>
    <major>1</major>
    <minor>0</minor>
  </specVersion>
  <URLBase>base URL for all relative URLs</URLBase>
  <device>
    <deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>
    <friendlyName>short user-friendly title</friendlyName>
    <manufacturer>manufacturer name</manufacturer>
    <manufacturerURL>URL to manufacturer site</manufacturerURL>
    <modelDescription>long user-friendly title</modelDescription>
    <modelName>model name</modelName>
    <modelNumber>model number</modelNumber>
    <modelURL>URL to model site</modelURL>
    <serialNumber>manufacturer's serial number</serialNumber>
    <UDN>uuid:UUID</UDN>
    <UPC>Universal Product Code</UPC>
    <iconList>
      <icon>
      <mimetype>image/format</mimetype>
      <width>horizontal pixels</width>
      <height>vertical pixels</height>
      <depth>color depth</depth>
      <url>URL to icon</url>
      </icon>
      <-- XML to declare other icons, if any, go here -->
    </iconList>
    <presentationURL>URL for presentation</presentationURL>
  </device>
</root>

Add Extended Content Directory Service Methods

ContentDirectory 1 Service

http://upnp.org/specs/av/UPnP-av-ContentDirectory-v1-Service.pdf

Method calls:

  • 2.7.1. GetSearchCapabilities
  • 2.7.2. GetSortCapabilities
  • 2.7.3. GetSystemUpdateID
  • 2.7.4. Browse
  • 2.7.5. Search
  • 2.7.6. CreateObject
  • 2.7.7. DestroyObject
  • 2.7.8. UpdateObject
  • 2.7.9. ImportResource
  • 2.7.10. ExportResource
  • 2.7.11. StopTransferResource
  • 2.7.12. GetTransferProgress
  • 2.7.13. DeleteResource
  • 2.7.14. CreateReference
  • 2.7.15. Non-Standard Actions Implemented by an UPnP Vendor

Create UPnP error class

When a network call results in an error, parse the resulting XML to a custom NSError object. The parser class should use libxml2, and use a custom domain - e.g. com.cocoaupnp.errordomain?

http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf (p. 80)

<!--
 HTTP/1.0 500 Internal Server Error
 CONTENT-TYPE: text/xml; charset="utf-8"
 DATE: when response was generated
 SERVER: OS/version UPnP/1.1 product/version
 CONTENT-LENGTH: bytes in body
-->
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
    <s:Fault>
      <faultcode>s:Client</faultcode>
      <faultstring>UPnPError</faultstring>
      <detail>
        <UPnPError xmlns="urn:schemas-upnp-org:control-1-0">
          <errorCode>error code</errorCode>
          <errorDescription>error string</errorDescription>
        </UPnPError>
      </detail>
    </s:Fault>
  </s:Body>
</s:Envelope>

The README.md doesn't say anything about the functionality

Hello,

Thanks for creating this library. I have no idea what it does though :) All that the description says is that "CocoaUPnP is a logical progression of upnpx". Then it just tells why it's not in Swift, that TDD was used for testing, that it relies on the following dependencies, tells us how to contribute and write unit tests if we contribute. But we still have no idea what we're invited to contribute to :)
After looking through the repo's README, I thought that maybe basic ideas are described in the aforementioned upnpx repo, which would be a bit unconvenient, but OK. However, the upnpx repo says literally the following:

upnpx
Fork of the discontinued upnpx library by Bruno Keymolen.
Including various logic and stability improvements over the last version.

And a licence :) Still have no idea what this lib does, and this time there's no link to dig deeper from the upnpx repo. All I can do is to try to find that discontinued library by Bruno Keymolen, which is hosted... somewhere... probably... or not ¯\_(ツ)_/¯

So, the bottom line is:
If you could add just a few words about what this library does, it's primary features and, maybe, how to use it, it would be really cool :)

Trying to stream an audio file to a renderer

Hi all.

I'm trying to incorporate CocoaUPnP into a project that requires streaming an mp3 audio file to a Raspberry Pi media renderer. I can connect and play an mp3 file that is hosted on a remote server (See hackey code below), but I'm not seeing anything in the framework to allow me to set data to the UPPAVTransportService to stream.

Super new to all this, and there's no documentation of how to stream a file. Any suggestions?

Note that if I can get this up and running, I'd be happy to write a full set-up guide for your wiki in exchange for help getting this working and/or shout a round of beers!

- (void) playTestSound {
    UPPMediaItem *item = [UPPMediaItem new];
    item.itemTitle = @"This is a test";
    item.objectClass = @"object.item.audioItem.musicTrack";
    item.objectID = @"0";
    item.parentID = @"1";
    item.isContainer = NO;
    item.durationInSeconds = (NSInteger) 20;
    item.artworkResources = [NSArray new];
    NSString *protocolInfo = @"http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000";
    UPPMediaItemResource *resource = [UPPMediaItemResource new];
    resource.protocolInfo = protocolInfo;
    resource.resourceURLString = @"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3";
    resource.duration = @"00:00:20";
   
    NSMutableArray *resources = [[NSMutableArray alloc] init];
    [resources addObject:resource];
    item.resources = resources;
    
    [self.playbackManager playItem:item];
}

tvOS Support

Would be cool to use this on tvOS instead of upnpx. But currently does not work.

GCDAsyncUdpSocket sendto error = EINPROGRESS

I've been digging through the code and this part feels off.

Around GCDAsyncUdpSocket.m:4200 it is checking if the result < 0 and marking it as a failure. But if I look at the error number, it is 36, and that is EINPROGRESS. What should actually happen at this point? Should it treat it as success�?

if (result == 0) { waitingForSocket = YES; } else if (result < 0) { int errorCode = EINPROGRESS; if (errorCode == EAGAIN) waitingForSocket = YES; else if (errorCode == EINPROGRESS || errorCode == EALREADY) { // Just let it through } else socketError = [self errnoErrorWithReason:@"Error in send() function."]; }

Browsing Windows Sharing services fails

When browsing a Windows Sharing CDS, network calls fail returning 402 - Invalid Args error.

An example request:

POST /upnphost/udhisapi.dll?control=uuid:5157631b-7c16-429a-8905-c732d5976d7c+urn:upnp-org:serviceId:ContentDirectory HTTP/1.1
Host: 10.54.6.195:2869
Content-Type: text/xml; charset="utf-8"
Connection: keep-alive
SOAPACTION: "urn:schemas-upnp-org:service:ContentDirectory:1#Browse"
Accept: */*
Accept-Language: en-us
Content-Length: 452
Accept-Encoding: gzip, deflate
User-Agent: MusicLife/667 CFNetwork/711.5.6 Darwin/14.0.0

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
    <u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">
      <ObjectID>0</ObjectID>
      <SortCriteria/>
      <StartingIndex>0</StartingIndex>
      <BrowseFlag>BrowseDirectChildren</BrowseFlag>
      <RequestedCount>32</RequestedCount>
      <Filter>*</Filter>
    </u:Browse>
  </s:Body>
</s:Envelope>

An example response:

HTTP/1.1 500 Internal Server Error
Content-Length: 498
Content-Type: text/xml; charset="utf-8"
Server: Microsoft-Windows-NT/5.1 UPnP/1.0 UPnP-Device-Host/1.0 Microsoft-HTTPAPI/2.0
Date: Tue, 08 Sep 2015 10:56:55 GMT


<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <SOAP-ENV:Fault>
      <faultcode>SOAP-ENV:Client</faultcode>
      <faultstring>UPnPError</faultstring>
      <detail>
        <u:UPnPError xmlns:u="urn:schemas-upnp-org:control-1-0">
          <u:errorCode>402</u:errorCode>
          <u:errorDescription>Invalid Args</u:errorDescription>
        </u:UPnPError>
      </detail>
    </SOAP-ENV:Fault>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

This is due to the Windows sharing service requiring SOAP XML keys to appear in the order they appear in the Service's spec.

How to subscription event

Hi friend,
pls help me, I dont know how to subscription event . if u can, pls show me a example

Thanks

Fetch all songs & metadata from server at once ?

Hi,

I am aware of the usual browse method which lets the user navigate through the server, but I would like to be able to fetch all songs and their metadata at once and then create my own way of navigating them.
Is there any way of doing so ?

thanks !

Media item title with or without extension

Hi,
I don't know if it's an issue or not, but with some media server when I browse with ContentdirectorryService the itemtitle returned is with the extension (For example "matrix.avi") and with some other server is without (just "matrix").
For my app I need to have always the same result.
Dio you know what can I do?
Thank you.

How to trap LastChange event?

Hello there - Thank you for this project!

I work exclusively in Swift, I manage to get a few things done in ObjC but it is definitely not my cup of tea.

I would like to add to the Example attached at the project the ability to track events and then parse the dictionary.

I understand how to parse the dictionary but I can't figure out how to create In the sample attached in the code subscriptions for events.

I got this far:
In the playbackManager.m I added:
(a dummy method)

UPPAVTransportService *avTransport = [self.renderer avTransportService]; [[UPPEventSubscriptionManager sharedManager] subscribeObserver:avTransport.observationInfo toService:avTransport completion:nil];

To the same file I added UPPEventSubscriptionDelegate delegate and comformed at it with:

- (void)eventReceived:(NSDictionary *)event { NSLog(@"%@ Event: %@", event.observationInfo, event.allKeys); }

I understand (because that what I would do in Swift) that I need to provide an observer and delegation to trap the events but again I have no clue on how to accomplish that in swift. Any chance, someone can post a chunk of code to receive events (LastChange is enough) so that I can learn and expand on that?

Thank you!

501 XML Error while setting AVTransportURI with parameters

Hi,

I'm facing an issue when setting AVTransportURI, the error I always get is a "501 - XML error".
When working with UPNP inspector (http://coherence.beebits.net/wiki/UPnP-Inspector) I don't have any problem.

Here is an exemple of URI I'm trying to set "vod://crid%3A%2F%2Fschange.com%2Fbetv.be%2FCTID000000141100/crid%3A%2F%2Fschange.com%2Fbetv.be%2FCTID000000141100%2Cimi%3A8a4e385d3f3d3ff02ac2d5fbcef5ffd9?trailer=no&position=1029890"

I tried without the url parameters (trailer & position) and it's working fine. So clearly it's the problem here. Any idea how to fix this ?

Once a device is detected it's not detected again

Hey, I'm facing a small issue : when I start the discovery, and successfully find the device I want, if I then stop the discovery and start it again some times later (a matter of seconds/minutes), it won't find the device anymore. Is that normal ?

Thanks :)

Basic Device protocol

A basic device should implement the following properties

bool isRoot;
bool isFound; // upnpx specific?
double lastUpdated;
NSMutableDictionary *services; //Key=urn string, Object=BasicUPnPService 
NSString *uuid;
NSString *type;
NSString *xmlLocation;
NSURL *baseURL;
NSString *baseURLString;
NSString *friendlyName;
NSString *manufacturer;
NSString *modelDescription;
NSString *modelName;
NSString *modelNumber;
NSString *serialNumber;
NSString *udn;
NSString *usn;
NSString *urn;
NSString *smallIconURL;

UPPMediaRendererDevice

Using sddp:all to search all devices, UPPMediaRendererDevice often fails to find or takes a long time.Do you have any suggestions?

Playlist issue

Hi,

First I don't know if it's an issue or not.
Maybe I don't do it correctly.

I try to send to a television a playlist of movies.

I try to do it like that:

func PLAY_liste(liste:[String]){
    _ = selectedPlayback.device.bindNext { (device:UPPMediaRendererDevice) in
        //Set the first URI to play
        device.avTransportService()?.setAVTransportURI(liste[0], currentURIMetaData: nil, instanceID: "0", success: { (ok, err) in
            
        })
        
    //Set all the next URIS
        for i in 1...liste.count-1 {
            device.avTransportService()?.setNextAVTransportURI(liste[i], nextURIMetaData: nil, instanceID: String(i), success: { (ok, err) in

            })
            
        }
        
//Play the first URI
        device.avTransportService()?.play(withInstanceID: "0", success: { (oklecture, erreur) in
            
    
        })
        
    }
}

The first URI is played correctly but the the next ones don't start.

Can you tell me what I do wrong? Or is it a bug?

Thank you in advance.

Best regards.

MediaItem protocol

Media item protocol should have the following properties

NSString *objectID;
NSString *parentID;
NSString *objectClass;
NSString *title;
NSString *albumArt;
NSString *artist;
BOOL isContainer;
NSString *album;
NSString *date;
NSString *genre;
NSString *originalTrackNumber;
NSString *uri;//Use uriCollection (uri contains the last element of uriCollection)
NSString *protocolInfo;//Use uriCollection (protocolInfo contains the last element of uriCollection)
NSString *frequency;
NSString *audioChannels;
NSString *size;
NSString *duration;
NSString *icon;
NSString *bitrate;
int durationInSeconds;
NSDictionary *uriCollection;//key: NSString* protocolinfo -> value:NSString* uri
NSMutableArray *resources;//MediaServer1ItemRes[]

The value for "USER-AGENT" in the M-SEARCH message does not comply to the UPnP standard. It also contains version issues.

When logging the SSDP messages from our iOS app with CocoaUPnP, we see that the M-SEARCH message has multiple issues for the "USER-AGENT" value.

Wireshark Log:

M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
ST: urn:schemas-upnp-org:device:MediaServer:1
MX: 3
USER-AGENT: My App/4 (iPhone; iOS 12.4) CocoaSSDP/0.1.0/1

Issues

  1. According to section 1.3.2 of the UPnP Device Architecture 1.1 the value should have the following syntax:
    USER-AGENT: OS/version UPnP/1.1 product/version

The first product token identifes the operating system in the form OS name/OS version, the second token represents the UPnP version and MUST be UPnP/1.1, and the third token identifes the product using the form
product name/product version. For example, “USER-AGENT: unix/5.1 UPnP/1.1 MyProduct/1.0”

This fails twice:

  • The mandatory second token UPnP/1.1 is missing
  • The third token contains an invalid 3rd element /1
  1. The first product token should only be OS name/OS version and no combination of app and OS between braces.

  2. The first product token shows the Build value from Xcode as version (4 in this example), instead of the Version string. Apparently the wrong key is used in _userAgentString, which should be "CFBundleShortVersionString":

    userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@) %@",
    bundleExecutable,
    (__bridge id)CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: bundleInfos[(__bridge NSString *)kCFBundleVersionKey],
    [[UIDevice currentDevice] model],
    [[UIDevice currentDevice] systemVersion], SSDPVersionString];

  3. The current version of CocoaSSDP is 2.0.2, not 0.1.0 as used in the user-agent. Root cause: A hardcoded const SSDPVersionString is used in SSDPServiceBrowser:

    NSString *const SSDPVersionString = @"CocoaSSDP/0.1.0";

Solution
To solve all these issues, I would recommend to follow the UPnP docu:
USER-AGENT: OS/version UPnP/1.1 product/version

For this example that would be:
USER-AGENT: iOS/12.4 UPnP/1.1 My App/1.2.3

That would also reduce maintaining SSDPVersionString, which obviously will be forgotten for each update.

So in code: remove /1 from USER_AGENT:

- (NSString *)_prepareSearchRequestWithServiceType:(NSString *)serviceType {
    NSString *userAgent = [self _userAgentString];

    return [NSString stringWithFormat:
            @"M-SEARCH * HTTP/1.1\r\n"
            "HOST: %@:%d\r\n"
            "MAN: \"ssdp:discover\"\r\n"
            "ST: %@\r\n"
            "MX: 3\r\n"
            "USER-AGENT: %@\r\n\r\n\r\n",
            SSDPMulticastGroupAddress,
            SSDPMulticastUDPPort,
            serviceType ?: @"ssdp:all",
            userAgent];
}

And apply proper syntax and use of correct keys to create the user-agent value:

- (NSString *)_userAgentString {
    NSString *userAgent = nil;
    NSDictionary *bundleInfos = [[NSBundle mainBundle] infoDictionary];
    NSString *bundleExecutable = bundleInfos[(__bridge NSString *)kCFBundleExecutableKey] ?: bundleInfos[(__bridge NSString *)kCFBundleIdentifierKey];

#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
    userAgent = [NSString stringWithFormat:@"%@/%@ UPnP/1.1 %@/%@",
                 [[UIDevice currentDevice] systemName],
                 [[UIDevice currentDevice] systemVersion],
                 bundleExecutable,
                 bundleInfos[@"CFBundleShortVersionString"]];

And similar for macOS.

Cross Frequency Detection

I'm not sure if this is an issue or something at my end.

My device runs on the 2.4ghz wifi frequency and my DLNA server was running on a 5ghz wifi frequency. While the frequency was different between the 2 devices, my device could not see the DLNA server.

The moment I swapped my DLNA server to run on 2.4ghz my device could see it perfectly.

Create AVTransport Service Class

AVTransport 1 Service Class

This service type enables control over the transport of audio and video streams.

http://upnp.org/specs/av/UPnP-av-AVTransport-v1-Service.pdf

TODO

  • 2.4.1. SetAVTransportURI
  • 2.4.2. SetNextAVTransportURI
  • 2.4.3. GetMediaInfo
  • 2.4.4. GetTransportInfo
  • 2.4.5. GetPositionInfo
  • 2.4.6. GetDeviceCapabilities
  • 2.4.7. GetTransportSettings
  • 2.4.8. Stop
  • 2.4.9. Play
  • 2.4.10. Pause
  • 2.4.11. Record
  • 2.4.12. Seek
  • 2.4.13. Next
  • 2.4.14. Previous
  • 2.4.15. SetPlayMode
  • 2.4.16. SetRecordQualityMode
  • 2.4.17. GetCurrentTransportActions

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.