|
mUPnP for C
|
This document describes how to use the mUPnP for Objective-C to create your UPnP™ devices and control points.
UPnP™*[^1] architecture is based on open networking to enable discovery and control of networked devices and services, such as media servers and players at home.
UPnP™ architecture is based on many standard protocols, such as GENA, SSDP, SOAP, HTTPU and HTTP. Therefore you have to understand and implement these protocols to create your devices of UPnP™.
mUPnP for Objective-C is a development package for UPnP™ developers on macOS and iOS. The mUPnP controls these protocols automatically, and supports to create your control points quickly.
Please see the following site and documents to know about UPnP™ in more detail.
| Document | URL |
|---|---|
| UPnP™ Forum | http://www.upnp.org/ |
| Universal Plug and Play Device Architecture | http://www.upnp.org/download/UPnPDA10_20000613.htm |
| Universal Plug and Play Vendor\'s Implementation Guide | http://www.upnp.org/download/UPnP_Vendor_Implementation_Guide_Jan2001.htm |
The Xcode projects target macOS 12.0 or later and iOS 15.0 or later. The wrapper sources in wrapper/objc/mUPnP use manual reference counting (MRC); the Xcode project compiles them with -fno-objc-arc, so add the same flag when you build them in an ARC target.
Build the framework with wrapper/objc/xcode/mUPnP4ObjC.xcodeproj. The project builds the C library through lib/macosx/xcode/libmupnp.xcodeproj and links it into the mUPnP4ObjC framework. To use the sources directly, add wrapper/objc/mUPnP/*.m to your target and add include and wrapper/objc to the header search paths.
The mUPnP4ObjCTests target contains XCTest cases for the wrapper. test/security/verify-macos.py builds the wrapper with ASan/UBSan and runs the Objective-C lifetime and API regressions together with the C test suite.
The following static structure diagram is related classes of mUPnP to create your control point of UPnP™. The control point has some root devices in the UPnP™ network.
To create a UPnP™ control point, create a instance of CGUpnpControlPoint class. The new instance is activated automatically using start (CGUpnpControlPoint), and init returns nil when the control point cannot be created or started. Use search (CGUpnpControlPoint) or searchWithST to find the devices in the local network.
search sends an M-SEARCH request with the search target upnp:rootdevice; use searchWithST: with ssdp:all or another target to search for other devices. The methods return once the request has been sent and do not wait for responses (unless the wrapper is compiled with CG_UPNPCONTROLPOINT_ENABLE_SEARCH_SLEEP, which waits for ssdpSearchMX seconds). Found devices are reported asynchronously through the CGUpnpControlPointDelegate methods and are returned by devices afterwards.
On iOS, the application that uses the control point needs a NSLocalNetworkUsageDescription entry, and sending SSDP multicast requires the multicast networking entitlement. Configure them in the application; the framework does not change entitlements or signing settings.
Use CGUpnpControlPoint:devices to get the all root devices which the control point found. The method returns a NSArray object which has the devices as instances of CGUpnpDevice. Each device is an independent snapshot taken when the method is called; it keeps its description after the device leaves the network, and it is not updated by later discovery or events.
The control point can send action or query control messages to the discovered devices. To send the action control message, use CGUpnpAction:setArgumentValue:forName and CGUpnpAction:post, or CGUpnpAction:postWithArguments. You should set the action values to the all input arguments, and the output argument values is ignored if you set. The following sample posts a action control request that sets a new time, and output the response result.
postWithArguments: checks every entry before it changes any argument or sends the request. It returns NO without sending anything when a key is not an argument name of the action, or when a key or value is not an NSString. Arguments that are not in the dictionary keep their current values.
Similarly, to send the query control message, use query (CGUpnpStateVariable). The following sample posts a query control request, and output the return value.
The SDK reports the result of each request but does not ask the user for confirmation or retry requests automatically. Applications that control real devices are responsible for confirming operations and for deciding whether to resend them.
CGUpnpDevice:parseXMLDescription and CGUpnpService:parseXMLDescription pass the description to the parser as UTF-8 bytes, so names that contain Japanese text or emoji are kept. They return NO without changing the receiver for nil, empty or non-UTF-8 input. When the XML itself is rejected, they return NO after the previous description has been cleared; do not use service, action or state variable objects obtained from the receiver before the failed call.
The Xcode framework exports its Objective-C headers and the mUPnP4ObjC Clang module. Objective-C framework consumers use #import <mUPnP4ObjC/CGUpnp.h> (the previous umbrella referenced a different framework name). Swift consumers can now use:
Build the shared mUPnP4ObjC scheme with an explicit SDK. The scheme includes only local XML XCTest fixtures. For a Mac test run:
Validated on Apple silicon with Xcode 27: unsigned macOS and generic Simulator builds, Swift consumer imports on both platforms, six Mac XCTest regressions, and python3 test/security/verify-macos.py /tmp/mupnp-sanitizers (ASan/UBSan Objective-C and C fixtures). This is not leak-detector coverage: macOS ASan has no LeakSanitizer, and the pre-existing C allowedValueList allocation leak is not fixed or certified by these runs. Any earlier Linux suppression remains a separate limitation. Failed XML reparse can invalidate child wrappers; do not keep child wrappers across reparsing their native owner. Async SOAP, NSError reporting and broader GENA/lifecycle changes remain separate work. No network discovery or physical control was exercised by the Swift imports.