# Cling Support

## User Manual

### Authors:

Christian Bauer

### Table Of Contents:

1. Working with InternetGatewayDevices

An InternetGatewayDevice connects a LAN to a WAN, and through UPnP supports the monitoring and configuration of LAN and WAN interfaces. Typically this functionality is used for NAT port mapping: A client application on the LAN wants to receive network connections from a WAN host, so it has to create a port forwarding and mapping on the LAN router.

1.1. Mapping a NAT port

Cling Support contains all the neccessary functionality, creating a port mapping on all NAT routers on a network requires only three lines of code:

    PortMapping desiredMapping =
            new PortMapping(
                    8123,
                    "192.168.0.123",
                    PortMapping.Protocol.TCP,
                    "My Port Mapping"
            );

    UpnpService upnpService =
            new UpnpServiceImpl(
                    new PortMappingListener(desiredMapping)
            );

    upnpService.getControlPoint().search();

The first line creates a port mapping configuration with the external/internal port, an internal host IP, the protocol and an optional description.

The second line starts the UPnP service with a special listener. This listener will add the port mapping on any InternetGatewayDevice with a WANIPConnection or a WANPPPConnection service as soon as it is discovered. You should immediately start a `ControlPoint#search()` for all devices on your network, this triggers a response and discovery of all NAT routers, activating the port mapping.

The listener will also delete the port mapping when you stop the UPnP stack through `UpnpService#shutdown()`, usually before your application quits. If you forget to shutdown the stack the port mapping will remain on the InternetGatewayDevice - the default lease duration is `0`!

If anything goes wrong, log messages with `WARNING` level will be created on the category `org.teleal.cling.support.igd.PortMappingListener`. You can override the `PortMappingListener#handleFailureMessage(String)` method to customize this behavior.

Alternatively, you can manually add and delete port mappings on an already discovered device with the following ready-to-use action callbacks:

    LocalService service = device.findService(new UDAServiceId("WANIPConnection"));

    upnpService.getControlPoint().execute(
            new PortMappingAddCallback(service, desiredMapping) {

                @Override
                public void success(ActionInvocation invocation) {
                    // All OK
                }

                @Override
                public void failure(ActionInvocation invocation, UpnpResponse operation) {
                    // Something is wrong
                }
            }
    );

    upnpService.getControlPoint().execute(
            new PortMappingDeleteCallback(service, desiredMapping) {

                @Override
                public void success(ActionInvocation invocation) {
                    // All OK
                }

                @Override
                public void failure(ActionInvocation invocation, UpnpResponse operation) {
                    // Something is wrong
                }
            }
    );

1.2. Getting connection information

The current connection information, including status, uptime, and last error message can be retrieved from a WAN*Connection service with the following callback:

    LocalService service = device.findService(new UDAServiceId("WANIPConnection"));

    upnpService.getControlPoint().execute(
            new GetStatusInfoCallback(service) {

                @Override
                protected void success(Connection.StatusInfo statusInfo) {
                    assertEquals(statusInfo.getStatus(), Connection.Status.Connected);
                    assertEquals(statusInfo.getUptimeSeconds(), 1000);
                    assertEquals(statusInfo.getLastError(), Connection.Error.ERROR_NONE);
                }

                @Override
                public void failure(ActionInvocation invocation, UpnpResponse operation) {
                    // Something is wrong
                }
            }
    );

Additionally, a callback for obtaining the external IP address of a connection is available:

    LocalService service = device.findService(new UDAServiceId("WANIPConnection"));

    upnpService.getControlPoint().execute(
            new GetExternalIPCallback(service) {

                @Override
                protected void success(String externalIPAddress) {
                    assertEquals(externalIPAddress, "123.123.123.123");
                }

                @Override
                public void failure(ActionInvocation invocation, UpnpResponse operation) {
                    // Something is wrong
                }
            }
    );

2. Sending messages to Samsung TVs

Many network-enabled Samsung TVs implement the proprietary samsung.com:MessageBoxService:1. The original purpose of this service was most likely connectivity with Samsung mobile phones; notification messages and alerts would appear on your TV when you are at home and your cellphone is connected to your local WiFi network (and your TV is turned on).

Cling Support delivers client classes for sending notifications to your Samsung TV via UPnP. (See this page for more information about the reverse-engineered raw message format.)

Sending messages from an Android handset
The XML parsing of messages requires Android 2.2, it won't work on any older version.

There are several message types available. The first is an SMS with a sender and receiver names and phone numbers, as well as a timestamp and message text:

    MessageSMS msg = new MessageSMS(
            new DateTime("2010-06-21", "16:34:12"),
            new NumberName("1234", "The Receiver"),
            new NumberName("5678", "The Sender"),
            "Hello World!"
    );

This message will appear as a "New SMS Received!" notification on your TV, with the option to reveal all message details. The other message types recognized by the TV are incoming call notification as well as calendar schedule reminder:

    MessageIncomingCall msg = new MessageIncomingCall(
            new DateTime("2010-06-21", "16:34:12"),
            new NumberName("1234", "The Callee"),
            new NumberName("5678", "The Caller")
    );

    MessageScheduleReminder msg = new MessageScheduleReminder(
            new DateTime("2010-06-21", "16:34:12"),
            new NumberName("1234", "The Owner"),
            "The Subject",
            new DateTime("2010-06-21", "17:34:12"),
            "The Location",
            "Hello World!"
    );

This is how you send a message asynchronously:

    LocalService service = device.findService(new ServiceId("samsung.com", "MessageBoxService"));

    upnpService.getControlPoint().execute(
            new AddMessageCallback(service, msg) {

                @Override
                public void success(ActionInvocation invocation) {
                    // All OK
                }

                @Override
                public void failure(ActionInvocation invocation, UpnpResponse operation) {
                    // Something is wrong
                }
            }
    );

Note that although your TV's service descriptor most likely contains a `RemoveMessage` action and Cling Support also ships with a `RemoveMessageCallback`, this action doesn't seem to be implemented by any Samsung TVs. Messages can only be deleted directly on the TV, with the remote control.

This manual has been created with Lemma from tested source code and Javadoc. Try it, you will like it.