Giter VIP home page Giter VIP logo

nmos-cpp's Introduction

An NMOS C++ Implementation Build Status

Introduction

This repository contains an implementation of the AMWA Networked Media Open Specifications in C++, licensed under the terms of the Apache License 2.0.

For more information about AMWA, NMOS and the Networked Media Incubator, please refer to http://amwa.tv/.

  • The nmos module includes implementations of the NMOS Node, Registration and Query APIs, the NMOS Connection API, and so on.
  • The nmos-cpp-registry application provides a simple but functional instance of an NMOS Registration & Discovery System (RDS), utilising the nmos module.
  • The nmos-cpp-node application provides an example NMOS Node, also utilising the nmos module.

The repository structure, and the external dependencies, are outlined in the documentation. Some information about the overall design of nmos-cpp is also included in the architecture documentation.

Getting Started With NMOS

The Easy-NMOS starter kit allows the user to launch a simple NMOS setup with minimal installation steps. It relies on a containerized nmos-cpp build to provide an NMOS Registry and a virtual NMOS Node in a Docker Compose network, along with the AMWA NMOS Testing Tool and supporting services.

Alternatively, it is possible to install a pre-built package for many platforms. See the instructions for installing with Conan.

Getting Started For Developers

Easy-NMOS is also a great first way to explore the relationship between NMOS services before building nmos-cpp for yourself.

The codebase is intended to be portable, and the nmos-cpp CMake project can be built on at least Linux, Windows and macOS.

After setting up the dependencies, follow these instructions to build and install nmos-cpp on your platform, and run the test suite.

Next, try out the registry and node applications in the tutorial.

An nmos-cpp Conan package is occasionally published at Conan Center Index.

Agile Development

JT-NM Tested 03/20 NMOS & TR-1001-1

The nmos-cpp applications, like the NMOS Specifications, are intended to be always ready, but steadily developing. They have been successfully tested in many AMWA Networked Media Incubator workshops, and are used as reference NMOS implementations in the JT-NM Tested programme. Several vendors have deployed JT-NM Tested badged products, using nmos-cpp, to their customers.

Build Status

The following configurations, defined by the build-test jobs, are built and unit tested automatically via continuous integration.

Platform Version Build Options Test Options
Linux Ubuntu 22.04 (GCC 11.2.0) Avahi Secure Communications
Multicast DNS-SD
Linux Ubuntu 22.04 (GCC 11.2.0) Avahi Secure Communications
IS-10 Authorization
Multicast DNS-SD
Linux Ubuntu 20.04 (GCC 9.4.0) Avahi Secure Communications
IS-10 Authorization
Multicast DNS-SD
Linux Ubuntu 20.04 (GCC 9.4.0) Avahi Secure Communications
IS-10 Authorization
Unicast DNS-SD
Linux Ubuntu 20.04 (GCC 9.4.0) mDNSResponder Secure Communications
IS-10 Authorization
Multicast DNS-SD
Linux Ubuntu 14.04 (GCC 4.8.4) mDNSResponder, not using Conan Secure Communications
IS-10 Authorization
Multicast DNS-SD
Windows Server 2019 (VS 2019) Bonjour (mDNSResponder), WinHTTP Secure Communications
IS-10 Authorization
Multicast DNS-SD
Windows Server 2022 (VS 2022) Bonjour (mDNSResponder), ASIO Secure Communications
Multicast DNS-SD
Windows Server 2022 (VS 2022) Bonjour (mDNSResponder), ASIO Secure Communications
IS-10 Authorization
Multicast DNS-SD
macOS 11 (AppleClang 13.0) Bonjour (mDNSResponder) Secure Communications
IS-10 Authorization
Multicast DNS-SD

The AMWA NMOS API Testing Tool is automatically run against the APIs of the nmos-cpp-node and nmos-cpp-registry applications.

Test Suite/Status: BCP-003-01 IS-04-01 IS-04-02 IS-04-03 IS-05-01 IS-05-02 IS-07-01 IS-07-02 IS-08-01 IS-08-02 IS-09-01 IS-09-02

Recent Activity

The implementation is designed to be extended. Development is ongoing, following the evolution of the NMOS specifications in the AMWA Networked Media Incubator.

Recent activity on the project (newest first):

  • Added support for the IS-12 NMOS Control Protocol
  • Update to Conan 2; Conan 1.X is no longer supported
  • Added support for IS-10 Authorization
  • Added support for HSTS and OCSP stapling
  • Added support for BCP-006-01 v1.0-dev, which can be demonstrated with nmos-cpp-node by using "video_type": "video/jxsv"
  • Updates to the GitHub Actions build-test workflow for better coverage of platforms and to include unicast DNS-SD tests
  • Regular Conan Center Index releases (see nmos-cpp recipe)
  • Update to RQL implementation to support advanced queries for string values containing '.'
  • Improvements to the SDP parser/generator
  • Improvements to Conan/CMake build, including updates to preferred version of dependencies such as Boost and OpenSSL
  • Prepared a basic Conan recipe for building nmos-cpp, in Sandbox/conan-recipe
  • Refactored the CMake build to make it easier to use nmos-cpp from another project, demonstrated by Sandbox/my-nmos-node
  • Added support for BCP-004-01 Receiver Capabilities
  • Switched CI testing to run the nmos-cpp applications and the AMWA NMOS Testing Tool with secure communication (TLS) enabled, as per BCP-003-01
  • Added support for the IS-08 Channel Mapping API
  • JT-NM Tested 03/20 badge
  • Switched Continous Integration to GitHub Actions and added Windows and macOS to the tested platforms
  • Extended the nmos-cpp-node to include mock senders/receivers of audio and ancillary data and offer some additional configuration settings
  • Simplified the build process to use Conan by default to download most of the dependencies
  • Added support in the Node implementation for discovery of, and interaction with, a System API, as required for compliance with TR-1001-1
  • Changed the implementation of nmos::tai_clock with the effect that it may no longer be monotonic
  • Added a minimum viable LLDP implementation (enabled by a CMake configuration option) to support sending and receiving the IS-04 v1.3 additional network data for Nodes required by IS-06
  • Update the IS-05 schemas to correct an unfortunate bug in the IS-05 v1.1 spec (see AMWA-TV/nmos-device-connection-management#99)
  • Attempt to determine the DNS domain name automatically if not explicitly specified, for TR-1001-1
  • Travis CI integration
  • Updates for resolutions of specification issues in IS-04 v1.3 and IS-05 v1.1 final drafts
  • Experimental support for human-readable HTML rendering of NMOS responses
  • Experimental support for the rehomed (work in progress) IS-09 System API (originally defined in JT-NM TR-1001-1:2018 Annex A)
  • IS-07 Events API and Events WebSocket API implementation and updated nmos-cpp-node example
  • Experimental support for secure communications (HTTPS, WSS)
  • Bug fixes (with test cases added to the AMWA NMOS API Testing Tool)
  • Support for running nmos-cpp applications with forward/reverse proxies
  • Experimental support for JT-NM TR-1001-1 System API
  • Instructions for cross-compiling for the Raspberry Pi
  • Instructions for running the official AMWA NMOS API Testing Tool
  • Updates to build instructions and required dependencies
  • Simpler creation/processing of the types of SDP files required to support ST 2110 and ST 2022-7
  • Simpler run-time configuration of the nmos-cpp-node and nmos-cpp-registry settings
  • Some documentation about the overall design of nmos-cpp for developers
  • An implementation of the Connection API
  • A fix for a potential memory leak
  • An SDP parser/generator (to/from a JSON representation)
  • JSON Schema validation in the Registration API and the Query API
  • Cross-platform build support using CMake
  • An initial release of the nmos-cpp-node example application
  • Back-end enhancements as part of the NMOS Scalability Activity

Contributing

We welcome bug reports, feature requests and contributions to the implementation and documentation. Please have a look at the simple Contribution Guidelines.

Thank you for your interest!

This project was formerly known as sea-lion.

nmos-cpp's People

Contributors

alanb-sony avatar billt-hlit avatar douglasheriot avatar garethsb avatar johanjino avatar jonathan-r-thorpe avatar jonvmey avatar jprui avatar jvandermey-evertz avatar jwpwh avatar lo-simon avatar n-nagorny avatar paulp-sony avatar prince-chrismc avatar rufusutt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nmos-cpp's Issues

SDP connection for multicast session

I have tried using the sdp_parameters for audio and have set the destination_ip in the transport parameters to the multicast address and the source_ip to the address of the device which is transmitting the multicast stream.

In the examples below, the address in the c= line is different and this seems pretty important. This is apparently decided at line 196 in sdp_utils.cpp. If the destination_ip is a multicast address, then it uses the source_ip. Otherwise, it uses the destination_ip. It seems like it should always use the destination_ip but maybe there is something going on with unicast sessions. RFC 4566 section 5.7 seems to indicate that for a multicast session, the address should be a multicast address and for a unicast it might be the source, or relay, or sink. Doesn't seem real clear for unicast but multicast seems pretty clear.

Am I using source_ip and destination_ip incorrectly for a multicast session or is line 196 in sdp_utils.cpp incorrect?

Line 196:
// setup Connection Data's connection address
const auto& connection_address = transport_param.at(address_type_multicast.second ? nmos::fields::source_ip : nmos::fields::destination_ip);

Example SDPs:

For one of my streams, the following SDP is generated using sdp_parameters

v=0
o=- 3753549510 3753549510 IN IP4 192.168.87.122
s=wnip:BL022S07:BL22:22.0.0.7
t=0 0
m=audio 50100 RTP/AVP 100
c=IN IP4 192.168.87.122/32
a=ts-refclk:ptp=IEEE1588-2008:traceable
a=mediaclk:direct=0
a=source-filter: incl IN IP4 239.192.197.171 192.168.87.122
a=ptime:0.25
a=rtpmap:100 L24/48000/2
a=fmtp:100 channel-order=SMPTE2110.(ST);

When I generate my own SDP file I get:

v=0
o=- 3753549224 3753549224 IN IP4 192.168.87.122
s=wnip:BL022S07:BL22:22.0.0.7
i=BL022S07 : BL22
c=IN IP4 239.192.197.171/255
t=0 0
m=audio 50100 RTP/AVP 100
a=recvonly
a=rtpmap:100 L24/48000/2
a=ptime:0.25
a=ts-refclk:ptp=IEEE1588-2008:00-00-00-00-00-00-00-00:4
a=mediaclk:direct=0

Test failures reported by mdns_test suite

I have completed set-up of all dependencies and nmos-cpp-registry-test could be ran successfully .

Next, I want to realize communication between node virtual machine and registry virtual machine over host machine.

So that I added virtual NIC to virtual machine to construct virtual private network where virtual machines can communicate with each other.
However, error of nmos-cpp-registry-test was occurred after addition of virtual NIC.

This is test result before addition of virtual NIC.

vagrant@node:~/nmos-cpp/Development/build$ ifconfig
eth0      Link encap:Ethernet  HWaddr 08:00:27:e2:80:18  
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fee2:8018/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1280 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1065 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:125443 (125.4 KB)  TX bytes:139851 (139.8 KB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:1456 (1.4 KB)  TX bytes:1456 (1.4 KB)

vagrant@node:~$ cd nmos-cpp/Development/build/
vagrant@node:~/nmos-cpp/Development/build$ ./nmos-cpp-registry-test
===============================================================================
All tests passed (260 assertions in 30 test cases)

And this is another test result after addition of virtual NIC.

vagrant@node:~$ ifconfig
eth0      Link encap:Ethernet  HWaddr 08:00:27:e2:80:18  
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fee2:8018/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1281 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1033 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:124571 (124.5 KB)  TX bytes:124271 (124.2 KB)

eth1      Link encap:Ethernet  HWaddr 08:00:27:9f:dd:38  
          inet addr:172.28.128.3  Bcast:172.28.128.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe9f:dd38/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1566 (1.5 KB)  TX bytes:1622 (1.6 KB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:1456 (1.4 KB)  TX bytes:1456 (1.4 KB)

vagrant@node:~$ cd nmos-cpp/Development/build/
vagrant@node:~/nmos-cpp/Development/build$ ./nmos-cpp-registry-test

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nmos-cpp-registry-test is a Catch v1.10.0 host application.
Run with -? for options

-------------------------------------------------------------------------------
testMdnsResolveAPIs
-------------------------------------------------------------------------------
/home/vagrant/nmos-cpp/Development/mdns/test/mdns_test.cpp:216
...............................................................................

/home/vagrant/nmos-cpp/Development/mdns/test/mdns_test.cpp:296: FAILED:
  CATCH_CHECK( ip_addresses == ipAddresses )
with expansion:
  {?} == {?}

===============================================================================
test cases:  30 |  29 passed | 1 failed
assertions: 260 | 259 passed | 1 failed

C++ REST SDK http_client doesn't fully support HTTP/1.0 with ASIO-based implementation

This only affects nmos-cpp Nodes which are built against cpprestsdk configured (at CMake time) with CPPREST_HTTP_CLIENT_IMPL=asio, which is the default on Linux but not Windows.

It only affects such Nodes when communicating with a Registry which only supports HTTP/1.0.
And it only causes any trouble when that Registry does not respond with a Connection: Keep-Alive header, but closes the connection after each response.

In this case, cpprestsdk still attempts to reuse the connection, and so the next request always fails.
This connection failure causes nmos-cpp Nodes to try the next available Registry.

This can be resolved by microsoft/cpprestsdk#1032, but this is not yet merged to cpprestsdk master.

node takes exception when registry exits

Scenario:

  • On windows 10, C++ REST SDK built with asio
  • Start registry on a different system. Happens to be a linux box running the registry. The registry is from sony/nmos-cpp.
  • Start nmos-cpp-node on the Windows system. (not as administrator)
  • Node comes up, registers the sample node, device, etc.. All is good
  • Go to linux box and kill the registry
  • The nmos-cpp-node running on the Windows system will exit. In the debugger, it takes an exception. The first non-system code is in cpprestsdk/install/include/cpprest/streams.h line 1094 and it looks like m_helper is empty so it is throwing an exception due to an uninitialized stream object. Call Stack attached below.
  • There are also two other instances of nmos-cpp-node running on a different linux system and these nodes do not crash. They are a little older and were not built with asio.

I have seen other issues talking about changes to cpprestsdk and I am not running with all the latest commits so it is possible that what I am seeing is already addressed. It did not seem like these other issues were seeing crashes when the registry terminated so it also seems possible that this is a new issue.

Has anyone else seen this? Thanks.

Call stack from the crash

CallStackExceptionWhenRegistryExits.txt

valgrind reports many "Conditional jump or move depends on uninitialised value(s)"

Hi, again,

I'm running valgrind in an attempt to find my own bugs but am seeing a lot of errors with uninitialized values in commit 91cb17d. I suspect a lot of the messages are a consequence of the first one -- the random number generator is seeded with something uninitialized, which means that all the uuids are uninitialzed, which means everything that refers to them are.

==21018== Memcheck, a memory error detector
==21018== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==21018== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==21018== Command: ./nmos-cpp-node {"host_name":\ "D13_04284",\ "logging_level":-11}
==21018== Parent PID: 27626
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x81FE380: boost::random::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u>::normalize_state() (mersenne_twister.hpp:351)
==21018==    by 0x81FDC16: void boost::random::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u>::seed<boost::uuids::detail::generator_iterator<boost::uuids::detail::seed_rng> >(boost::uuids::detail::generator_iterator<boost::uuids::detail::seed_rng>&, boost::uuids::detail::generator_iterator<boost::uuids::detail::seed_rng>) (mersenne_twister.hpp:176)
==21018==    by 0x81FD1C5: void boost::uuids::detail::seed<boost::random::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u> >(boost::random::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u>&) (seed_rng.hpp:249)
==21018==    by 0x81FC29E: boost::uuids::basic_random_generator<boost::random::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u> >::basic_random_generator() (random_generator.hpp:50)
==21018==    by 0x81FAB51: nmos::make_id[abi:cxx11]() (id.h:19)
==21018==    by 0x8248ADB: nmos::experimental::make_node_resources(boost::multi_index::multi_index_container<nmos::resource, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<nmos::tags::id, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, &nmos::resource_core::id>, mpl_::na, mpl_::na>, boost::multi_index::ordered_non_unique<boost::multi_index::tag<nmos::tags::type, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::type, &nmos::resource_core::type>, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::created, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::created>, std::greater<nmos::tai> >, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::updated, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::updated>, std::greater<nmos::tai> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<nmos::resource> >&, web::json::value const&) (node_resources.cpp:281)
==21018==    by 0x81426C0: main (main.cpp:131)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x81FE3CD: boost::random::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u>::normalize_state() (mersenne_twister.hpp:360)
==21018==    by 0x81FDC16: void boost::random::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u>::seed<boost::uuids::detail::generator_iterator<boost::uuids::detail::seed_rng> >(boost::uuids::detail::generator_iterator<boost::uuids::detail::seed_rng>&, boost::uuids::detail::generator_iterator<boost::uuids::detail::seed_rng>) (mersenne_twister.hpp:176)
==21018==    by 0x81FD1C5: void boost::uuids::detail::seed<boost::random::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u> >(boost::random::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u>&) (seed_rng.hpp:249)
==21018==    by 0x81FC29E: boost::uuids::basic_random_generator<boost::random::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u> >::basic_random_generator() (random_generator.hpp:50)
==21018==    by 0x81FAB51: nmos::make_id[abi:cxx11]() (id.h:19)
==21018==    by 0x8248ADB: nmos::experimental::make_node_resources(boost::multi_index::multi_index_container<nmos::resource, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<nmos::tags::id, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, &nmos::resource_core::id>, mpl_::na, mpl_::na>, boost::multi_index::ordered_non_unique<boost::multi_index::tag<nmos::tags::type, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::type, &nmos::resource_core::type>, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::created, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::created>, std::greater<nmos::tai> >, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::updated, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::updated>, std::greater<nmos::tai> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<nmos::resource> >&, web::json::value const&) (node_resources.cpp:281)
==21018==    by 0x81426C0: main (main.cpp:131)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x81FA9AD: boost::uuids::detail::to_char(unsigned int) (uuid_io.hpp:132)
==21018==    by 0x81FAA48: boost::uuids::to_string[abi:cxx11](boost::uuids::uuid const&) (uuid_io.hpp:157)
==21018==    by 0x81FAB77: nmos::make_id[abi:cxx11]() (id.h:19)
==21018==    by 0x8248ADB: nmos::experimental::make_node_resources(boost::multi_index::multi_index_container<nmos::resource, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<nmos::tags::id, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, &nmos::resource_core::id>, mpl_::na, mpl_::na>, boost::multi_index::ordered_non_unique<boost::multi_index::tag<nmos::tags::type, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::type, &nmos::resource_core::type>, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::created, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::created>, std::greater<nmos::tai> >, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::updated, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::updated>, std::greater<nmos::tai> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<nmos::resource> >&, web::json::value const&) (node_resources.cpp:281)
==21018==    by 0x81426C0: main (main.cpp:131)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x81FA9AD: boost::uuids::detail::to_char(unsigned int) (uuid_io.hpp:132)
==21018==    by 0x81FAA77: boost::uuids::to_string[abi:cxx11](boost::uuids::uuid const&) (uuid_io.hpp:160)
==21018==    by 0x81FAB77: nmos::make_id[abi:cxx11]() (id.h:19)
==21018==    by 0x8248ADB: nmos::experimental::make_node_resources(boost::multi_index::multi_index_container<nmos::resource, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<nmos::tags::id, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, &nmos::resource_core::id>, mpl_::na, mpl_::na>, boost::multi_index::ordered_non_unique<boost::multi_index::tag<nmos::tags::type, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::type, &nmos::resource_core::type>, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::created, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::created>, std::greater<nmos::tai> >, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::updated, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::updated>, std::greater<nmos::tai> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<nmos::resource> >&, web::json::value const&) (node_resources.cpp:281)
==21018==    by 0x81426C0: main (main.cpp:131)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x81FA9AD: boost::uuids::detail::to_char(unsigned int) (uuid_io.hpp:132)
==21018==    by 0x81FAA48: boost::uuids::to_string[abi:cxx11](boost::uuids::uuid const&) (uuid_io.hpp:157)
==21018==    by 0x81FAB77: nmos::make_id[abi:cxx11]() (id.h:19)
==21018==    by 0x8248AED: nmos::experimental::make_node_resources(boost::multi_index::multi_index_container<nmos::resource, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<nmos::tags::id, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, &nmos::resource_core::id>, mpl_::na, mpl_::na>, boost::multi_index::ordered_non_unique<boost::multi_index::tag<nmos::tags::type, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::type, &nmos::resource_core::type>, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::created, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::created>, std::greater<nmos::tai> >, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::updated, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::updated>, std::greater<nmos::tai> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<nmos::resource> >&, web::json::value const&) (node_resources.cpp:282)
==21018==    by 0x81426C0: main (main.cpp:131)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x81FA9AD: boost::uuids::detail::to_char(unsigned int) (uuid_io.hpp:132)
==21018==    by 0x81FAA77: boost::uuids::to_string[abi:cxx11](boost::uuids::uuid const&) (uuid_io.hpp:160)
==21018==    by 0x81FAB77: nmos::make_id[abi:cxx11]() (id.h:19)
==21018==    by 0x8248AED: nmos::experimental::make_node_resources(boost::multi_index::multi_index_container<nmos::resource, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<nmos::tags::id, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, &nmos::resource_core::id>, mpl_::na, mpl_::na>, boost::multi_index::ordered_non_unique<boost::multi_index::tag<nmos::tags::type, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::type, &nmos::resource_core::type>, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::created, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::created>, std::greater<nmos::tai> >, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::updated, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::updated>, std::greater<nmos::tai> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<nmos::resource> >&, web::json::value const&) (node_resources.cpp:282)
==21018==    by 0x81426C0: main (main.cpp:131)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x81FA9AD: boost::uuids::detail::to_char(unsigned int) (uuid_io.hpp:132)
==21018==    by 0x81FAA48: boost::uuids::to_string[abi:cxx11](boost::uuids::uuid const&) (uuid_io.hpp:157)
==21018==    by 0x81FAB77: nmos::make_id[abi:cxx11]() (id.h:19)
==21018==    by 0x8248AFF: nmos::experimental::make_node_resources(boost::multi_index::multi_index_container<nmos::resource, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<nmos::tags::id, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, &nmos::resource_core::id>, mpl_::na, mpl_::na>, boost::multi_index::ordered_non_unique<boost::multi_index::tag<nmos::tags::type, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::type, &nmos::resource_core::type>, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::created, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::created>, std::greater<nmos::tai> >, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::updated, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::updated>, std::greater<nmos::tai> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<nmos::resource> >&, web::json::value const&) (node_resources.cpp:283)
==21018==    by 0x81426C0: main (main.cpp:131)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x81FA9AD: boost::uuids::detail::to_char(unsigned int) (uuid_io.hpp:132)
==21018==    by 0x81FAA77: boost::uuids::to_string[abi:cxx11](boost::uuids::uuid const&) (uuid_io.hpp:160)
==21018==    by 0x81FAB77: nmos::make_id[abi:cxx11]() (id.h:19)
==21018==    by 0x8248AFF: nmos::experimental::make_node_resources(boost::multi_index::multi_index_container<nmos::resource, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<nmos::tags::id, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, &nmos::resource_core::id>, mpl_::na, mpl_::na>, boost::multi_index::ordered_non_unique<boost::multi_index::tag<nmos::tags::type, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::type, &nmos::resource_core::type>, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::created, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::created>, std::greater<nmos::tai> >, boost::multi_index::ordered_unique<boost::multi_index::tag<nmos::tags::updated, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<nmos::resource_core, nmos::tai, &nmos::resource_core::updated>, std::greater<nmos::tai> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<nmos::resource> >&, web::json::value const&) (node_resources.cpp:283)
==21018==    by 0x81426C0: main (main.cpp:131)
==21018== 
==21018== Thread 2:
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x81FA9AD: boost::uuids::detail::to_char(unsigned int) (uuid_io.hpp:132)
==21018==    by 0x81FAA48: boost::uuids::to_string[abi:cxx11](boost::uuids::uuid const&) (uuid_io.hpp:157)
==21018==    by 0x81FAB77: nmos::make_id[abi:cxx11]() (id.h:19)
==21018==    by 0x81FB978: nmos::experimental::details::json_from_message(slog::async_log_message const&) (logging_api.cpp:185)
==21018==    by 0x81F566A: nmos::experimental::log_to_model(nmos::experimental::log_model&, slog::async_log_message const&) (logging_api.cpp:198)
==21018==    by 0x81419D8: (anonymous namespace)::main_gate::service(slog::async_log_message const&) (main_gate.h:65)
==21018==    by 0x8141888: (anonymous namespace)::main_gate::service_function::operator()(slog::async_log_message const&) const (main_gate.h:50)
==21018==    by 0x8143A09: void util::message_service<slog::async_log_message>::run<(anonymous namespace)::main_gate::service_function>((anonymous namespace)::main_gate::service_function const&) (all_in_one.h:2868)
==21018==    by 0x814352B: slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1}::operator()() const (all_in_one.h:2940)
==21018==    by 0x8148CEB: void std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) (functional:1531)
==21018==    by 0x8148BFE: std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::operator()() (functional:1520)
==21018==    by 0x8148B3A: std::thread::_Impl<std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()> >::_M_run() (thread:115)
==21018==    by 0x4EC662D: ??? (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.21)
==21018==    by 0x4BBB294: start_thread (pthread_create.c:333)
==21018==    by 0x50FA0AD: clone (clone.S:114)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x81FA9AD: boost::uuids::detail::to_char(unsigned int) (uuid_io.hpp:132)
==21018==    by 0x81FAA77: boost::uuids::to_string[abi:cxx11](boost::uuids::uuid const&) (uuid_io.hpp:160)
==21018==    by 0x81FAB77: nmos::make_id[abi:cxx11]() (id.h:19)
==21018==    by 0x81FB978: nmos::experimental::details::json_from_message(slog::async_log_message const&) (logging_api.cpp:185)
==21018==    by 0x81F566A: nmos::experimental::log_to_model(nmos::experimental::log_model&, slog::async_log_message const&) (logging_api.cpp:198)
==21018==    by 0x81419D8: (anonymous namespace)::main_gate::service(slog::async_log_message const&) (main_gate.h:65)
==21018==    by 0x8141888: (anonymous namespace)::main_gate::service_function::operator()(slog::async_log_message const&) const (main_gate.h:50)
==21018==    by 0x8143A09: void util::message_service<slog::async_log_message>::run<(anonymous namespace)::main_gate::service_function>((anonymous namespace)::main_gate::service_function const&) (all_in_one.h:2868)
==21018==    by 0x814352B: slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1}::operator()() const (all_in_one.h:2940)
==21018==    by 0x8148CEB: void std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) (functional:1531)
==21018==    by 0x8148BFE: std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::operator()() (functional:1520)
==21018==    by 0x8148B3A: std::thread::_Impl<std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()> >::_M_run() (thread:115)
==21018==    by 0x4EC662D: ??? (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.21)
==21018==    by 0x4BBB294: start_thread (pthread_create.c:333)
==21018==    by 0x50FA0AD: clone (clone.S:114)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x4806C5A: web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}::operator()(char) const (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480796A: bool __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>::operator()<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x48077AD: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::__find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}> >(__gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, std::random_access_iterator_tag) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807739: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::__find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}> >(__gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x48076A3: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807635: bool std::none_of<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807600: bool std::any_of<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4806CE2: web::json::details::_String::has_escape_chars(web::json::details::_String const&) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480A3FA: web::json::details::_String::_String(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480D9AC: std::unique_ptr<web::json::details::_String, std::default_delete<web::json::details::_String> > utility::details::make_unique<web::json::details::_String, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4806373: web::json::value::string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x81FB991: nmos::experimental::details::json_from_message(slog::async_log_message const&) (logging_api.cpp:185)
==21018==    by 0x81F566A: nmos::experimental::log_to_model(nmos::experimental::log_model&, slog::async_log_message const&) (logging_api.cpp:198)
==21018==    by 0x81419D8: (anonymous namespace)::main_gate::service(slog::async_log_message const&) (main_gate.h:65)
==21018==    by 0x8141888: (anonymous namespace)::main_gate::service_function::operator()(slog::async_log_message const&) const (main_gate.h:50)
==21018==    by 0x8143A09: void util::message_service<slog::async_log_message>::run<(anonymous namespace)::main_gate::service_function>((anonymous namespace)::main_gate::service_function const&) (all_in_one.h:2868)
==21018==    by 0x814352B: slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1}::operator()() const (all_in_one.h:2940)
==21018==    by 0x8148CEB: void std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) (functional:1531)
==21018==    by 0x8148BFE: std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::operator()() (functional:1520)
==21018==    by 0x8148B3A: std::thread::_Impl<std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()> >::_M_run() (thread:115)
==21018==    by 0x4EC662D: ??? (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.21)
==21018==    by 0x4BBB294: start_thread (pthread_create.c:333)
==21018==    by 0x50FA0AD: clone (clone.S:114)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x4806C67: web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}::operator()(char) const (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480796A: bool __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>::operator()<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x48077AD: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::__find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}> >(__gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, std::random_access_iterator_tag) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807739: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::__find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}> >(__gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x48076A3: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807635: bool std::none_of<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807600: bool std::any_of<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4806CE2: web::json::details::_String::has_escape_chars(web::json::details::_String const&) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480A3FA: web::json::details::_String::_String(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480D9AC: std::unique_ptr<web::json::details::_String, std::default_delete<web::json::details::_String> > utility::details::make_unique<web::json::details::_String, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4806373: web::json::value::string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x81FB991: nmos::experimental::details::json_from_message(slog::async_log_message const&) (logging_api.cpp:185)
==21018==    by 0x81F566A: nmos::experimental::log_to_model(nmos::experimental::log_model&, slog::async_log_message const&) (logging_api.cpp:198)
==21018==    by 0x81419D8: (anonymous namespace)::main_gate::service(slog::async_log_message const&) (main_gate.h:65)
==21018==    by 0x8141888: (anonymous namespace)::main_gate::service_function::operator()(slog::async_log_message const&) const (main_gate.h:50)
==21018==    by 0x8143A09: void util::message_service<slog::async_log_message>::run<(anonymous namespace)::main_gate::service_function>((anonymous namespace)::main_gate::service_function const&) (all_in_one.h:2868)
==21018==    by 0x814352B: slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1}::operator()() const (all_in_one.h:2940)
==21018==    by 0x8148CEB: void std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) (functional:1531)
==21018==    by 0x8148BFE: std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::operator()() (functional:1520)
==21018==    by 0x8148B3A: std::thread::_Impl<std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()> >::_M_run() (thread:115)
==21018==    by 0x4EC662D: ??? (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.21)
==21018==    by 0x4BBB294: start_thread (pthread_create.c:333)
==21018==    by 0x50FA0AD: clone (clone.S:114)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x4806C74: web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}::operator()(char) const (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480796A: bool __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>::operator()<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x48077AD: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::__find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}> >(__gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, std::random_access_iterator_tag) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807739: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::__find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}> >(__gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x48076A3: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807635: bool std::none_of<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807600: bool std::any_of<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4806CE2: web::json::details::_String::has_escape_chars(web::json::details::_String const&) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480A3FA: web::json::details::_String::_String(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480D9AC: std::unique_ptr<web::json::details::_String, std::default_delete<web::json::details::_String> > utility::details::make_unique<web::json::details::_String, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4806373: web::json::value::string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x81FB991: nmos::experimental::details::json_from_message(slog::async_log_message const&) (logging_api.cpp:185)
==21018==    by 0x81F566A: nmos::experimental::log_to_model(nmos::experimental::log_model&, slog::async_log_message const&) (logging_api.cpp:198)
==21018==    by 0x81419D8: (anonymous namespace)::main_gate::service(slog::async_log_message const&) (main_gate.h:65)
==21018==    by 0x8141888: (anonymous namespace)::main_gate::service_function::operator()(slog::async_log_message const&) const (main_gate.h:50)
==21018==    by 0x8143A09: void util::message_service<slog::async_log_message>::run<(anonymous namespace)::main_gate::service_function>((anonymous namespace)::main_gate::service_function const&) (all_in_one.h:2868)
==21018==    by 0x814352B: slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1}::operator()() const (all_in_one.h:2940)
==21018==    by 0x8148CEB: void std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) (functional:1531)
==21018==    by 0x8148BFE: std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::operator()() (functional:1520)
==21018==    by 0x8148B3A: std::thread::_Impl<std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()> >::_M_run() (thread:115)
==21018==    by 0x4EC662D: ??? (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.21)
==21018==    by 0x4BBB294: start_thread (pthread_create.c:333)
==21018==    by 0x50FA0AD: clone (clone.S:114)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x4806C5A: web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}::operator()(char) const (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480796A: bool __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>::operator()<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x48077DF: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::__find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}> >(__gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, std::random_access_iterator_tag) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807739: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::__find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}> >(__gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x48076A3: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807635: bool std::none_of<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807600: bool std::any_of<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4806CE2: web::json::details::_String::has_escape_chars(web::json::details::_String const&) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480A3FA: web::json::details::_String::_String(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480D9AC: std::unique_ptr<web::json::details::_String, std::default_delete<web::json::details::_String> > utility::details::make_unique<web::json::details::_String, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4806373: web::json::value::string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x81FB991: nmos::experimental::details::json_from_message(slog::async_log_message const&) (logging_api.cpp:185)
==21018==    by 0x81F566A: nmos::experimental::log_to_model(nmos::experimental::log_model&, slog::async_log_message const&) (logging_api.cpp:198)
==21018==    by 0x81419D8: (anonymous namespace)::main_gate::service(slog::async_log_message const&) (main_gate.h:65)
==21018==    by 0x8141888: (anonymous namespace)::main_gate::service_function::operator()(slog::async_log_message const&) const (main_gate.h:50)
==21018==    by 0x8143A09: void util::message_service<slog::async_log_message>::run<(anonymous namespace)::main_gate::service_function>((anonymous namespace)::main_gate::service_function const&) (all_in_one.h:2868)
==21018==    by 0x814352B: slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1}::operator()() const (all_in_one.h:2940)
==21018==    by 0x8148CEB: void std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) (functional:1531)
==21018==    by 0x8148BFE: std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::operator()() (functional:1520)
==21018==    by 0x8148B3A: std::thread::_Impl<std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()> >::_M_run() (thread:115)
==21018==    by 0x4EC662D: ??? (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.21)
==21018==    by 0x4BBB294: start_thread (pthread_create.c:333)
==21018==    by 0x50FA0AD: clone (clone.S:114)
==21018== 
==21018== Conditional jump or move depends on uninitialised value(s)
==21018==    at 0x4806C67: web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}::operator()(char) const (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480796A: bool __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>::operator()<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x48077DF: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::__find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}> >(__gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, std::random_access_iterator_tag) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807739: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::__find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}> >(__gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>, __gnu_cxx::__ops::_Iter_pred<web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x48076A3: __gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::find_if<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807635: bool std::none_of<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4807600: bool std::any_of<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}>(__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}, web::json::details::_String::has_escape_chars(web::json::details::_String const&)::{lambda(char)#1}) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4806CE2: web::json::details::_String::has_escape_chars(web::json::details::_String const&) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480A3FA: web::json::details::_String::_String(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x480D9AC: std::unique_ptr<web::json::details::_String, std::default_delete<web::json::details::_String> > utility::details::make_unique<web::json::details::_String, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x4806373: web::json::value::string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (in /usr/local/lib/libcpprest.so.2.10)
==21018==    by 0x81FB991: nmos::experimental::details::json_from_message(slog::async_log_message const&) (logging_api.cpp:185)
==21018==    by 0x81F566A: nmos::experimental::log_to_model(nmos::experimental::log_model&, slog::async_log_message const&) (logging_api.cpp:198)
==21018==    by 0x81419D8: (anonymous namespace)::main_gate::service(slog::async_log_message const&) (main_gate.h:65)
==21018==    by 0x8141888: (anonymous namespace)::main_gate::service_function::operator()(slog::async_log_message const&) const (main_gate.h:50)
==21018==    by 0x8143A09: void util::message_service<slog::async_log_message>::run<(anonymous namespace)::main_gate::service_function>((anonymous namespace)::main_gate::service_function const&) (all_in_one.h:2868)
==21018==    by 0x814352B: slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1}::operator()() const (all_in_one.h:2940)
==21018==    by 0x8148CEB: void std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) (functional:1531)
==21018==    by 0x8148BFE: std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()>::operator()() (functional:1520)
==21018==    by 0x8148B3A: std::thread::_Impl<std::_Bind_simple<slog::async_log_service<(anonymous namespace)::main_gate::service_function, slog::async_log_message>::async_log_service((anonymous namespace)::main_gate::service_function)::{lambda()#1} ()> >::_M_run() (thread:115)

How to deal with real media file and real media device?

I want to implement that sending and receiveing video file captured by device which is connected to real host machine according to media transport protocol between sender and receiver of virtual node.

Current open nmos-cpp application of node and registry implements communication between node and registry that send/receive virtual informations of device, media and so on.
Now then, does nmos-cpp application have function to deal with real device(e.g. USB Web camera) and send/receive real media file(e.g. H.264 video) according to media transport protocol(e.g. RTP) ?

If there were such functions, what action or editing of source code is necessary to use such functions?

nmos-cpp apps need to be launched with admin privileges on Windows

This is because the http_listeners want to work on all interfaces, and the C++ REST SDK implementation which uses the Microsoft HTTP libraries by default, requires that admin privileges.

If you build C++ REST SDK with CPPREST_HTTP_CLIENT_IMPL:STRING=asio and CPPREST_HTTP_LISTENER_IMPL:STRING=asio, admin privileges aren't necessary.

This should be documented in Dependencies.

Thanks to @datkins47 for the reminder.

nmos-cpp-registry performance problems?

Hi, Gareth,

I'm using nmos-cpp-registry to test my changes to nmos-cpp-node and am seeing some excess CPU consumption by the registry. My basic set-up is to run the AMWA nmos-testing python script on one machine, the node on the target platform, and the registry on a third machine running Ubuntu 18.04 that happens to be on a different subnet. There is also an instance of Riedel's NMOS Explorer running on the registry machine.

Due to the huge number of Receivers on the target and the carelessness with which I update the Receivers when something changes, the target is sending large numbers of registry updates. As a result, nmos-cpp-registry ends up consuming a little more than a whole CPU of the machine it's running on, and the registry updates continue long after nmos-testing has finished its tests and rendered its results to the web browser.

I monitored the program's behavior using "perf top -p" which you can see below. The one thing that really strikes me is how much time it is spending in SHA-1 processing in boost::uuids. I don't know what that's for, but maybe there's a caching opportunity there to reduce the UUID computation.

   5.05%  nmos-cpp-registry          [.] _ZN5boost5uuids6detail4sha113process_blockEv
   3.63%  nmos-cpp-registry          [.] _ZZNKSt8__detail15_BracketMatcherINSt7__cxx1112regex_traitsIcEELb0ELb0EE8_M_applyEcSt17integral_constantIbLb0EEENKUlvE_clEv
   2.83%  libc-2.27.so               [.] cfree@GLIBC_2.2.5
   2.63%  libstdc++.so.6.0.25        [.] __dynamic_cast
   2.26%  libstdc++.so.6.0.25        [.] _ZNK10__cxxabiv121__vmi_class_type_info12__do_dyncastElNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE
   2.07%  nmos-cpp-registry          [.] _ZN5boost5uuids6detail11left_rotateEjm
   1.67%  libstdc++.so.6.0.25        [.] _ZNKSt7__cxx117collateIcE12do_transformEPKcS3_
   1.66%  libc-2.27.so               [.] malloc
   1.24%  libc-2.27.so               [.] __GI___strcmp_ssse3
   1.23%  nmos-cpp-registry          [.] _ZN5boost5uuids6detail4sha112process_byteEh
   1.15%  nmos-cpp-registry          [.] _ZN5boost5uuids6detail4sha117process_byte_implEh
   1.13%  nmos-cpp-registry          [.] _ZNSt6vectorIcSaIcEE4dataEv
   1.07%  [kernel]                   [k] thread_group_cputime
   1.00%  nmos-cpp-registry          [.] _ZSt8distanceIPKcENSt15iterator_traitsIT_E15difference_typeES3_S3_
   0.98%  nmos-cpp-registry          [.] _ZNKSt7__cxx1112regex_traitsIcE17transform_primaryIPKcEENS_12basic_stringIcSt11char_traitsIcESaIcEEET_SA_
   0.91%  nmos-cpp-registry          [.] _ZN9__gnu_cxxneIPKSt4pairIccESt6vectorIS2_SaIS2_EEEEbRKNS_17__normal_iteratorIT_T0_EESD_
   0.88%  nmos-cpp-registry          [.] _ZNKSt7__cxx1112regex_traitsIcE9transformIPcEENS_12basic_stringIcSt11char_traitsIcESaIcEEET_S9_
   0.88%  nmos-cpp-registry          [.] _ZN9__gnu_cxx17__normal_iteratorIPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIS6_SaIS6_EEEC2ERKS8_
   0.84%  nmos-cpp-registry          [.] _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag
   0.78%  libstdc++.so.6.0.25        [.] _ZNK10__cxxabiv120__si_class_type_info12__do_dyncastElNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE
   0.78%  nmos-cpp-registry          [.] _ZN9__gnu_cxxmiIPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIS6_SaIS6_EEEENS_17__normal_iteratorIT_T0_E15difference_typeERKSF_SI_
   0.76%  nmos-cpp-registry          [.] _ZSt13binary_searchIN9__gnu_cxx17__normal_iteratorIPKcSt6vectorIcSaIcEEEEcEbT_S8_RKT0_
   0.76%  nmos-cpp-registry          [.] _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPcEEvT_S7_St20forward_iterator_tag
   0.73%  nmos-cpp-registry          [.] _ZNSt8__detail15_BracketMatcherINSt7__cxx1112regex_traitsIcEELb0ELb0EE13_M_make_cacheESt17integral_constantIbLb1EE
   0.72%  nmos-cpp-registry          [.] _ZNKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE3endEv
   0.71%  nmos-cpp-registry          [.] _ZNKSt6vectorIcSaIcEE4sizeEv
   0.69%  nmos-cpp-registry          [.] _ZNKSt6vectorIcSaIcEE11_M_data_ptrIcEEPT_S4_
   0.66%  nmos-cpp-registry          [.] _ZNSt6vectorIcSaIcEE19_M_range_initializeIPKcEEvT_S5_St20forward_iterator_tag
   0.63%  nmos-cpp-registry          [.] _ZNSt6bitsetILm256EE9referenceaSEb
   0.63%  nmos-cpp-registry          [.] _ZSt13__lower_boundIN9__gnu_cxx17__normal_iteratorIPKcSt6vectorIcSaIcEEEEcNS0_5__ops14_Iter_less_valEET_SA_SA_RKT0_T1_
   0.63%  libc-2.27.so               [.] __strxfrm_l
   0.60%  nmos-cpp-registry          [.] _ZSt9__find_ifIN9__gnu_cxx17__normal_iteratorIPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIS7_SaIS7_EEEENS0_5__ops16_Iter_equals_va
   0.59%  nmos-cpp-registry          [.] _ZN9__gnu_cxx17__normal_iteratorIPKcSt6vectorIcSaIcEEEC2ERKS2_
   0.58%  nmos-cpp-registry          [.] _ZN9__gnu_cxx17__normal_iteratorIPKSt4pairIccESt6vectorIS2_SaIS2_EEEC2ERKS4_
   0.58%  nmos-cpp-registry          [.] _ZNSt12_Vector_baseIcSaIcEED2Ev
   0.58%  nmos-cpp-registry          [.] _ZNKSt8__detail15_BracketMatcherINSt7__cxx1112regex_traitsIcEELb0ELb0EE8_M_applyEcSt17integral_constantIbLb0EE
   0.58%  nmos-cpp-registry          [.] _ZNK9__gnu_cxx17__normal_iteratorIPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIS6_SaIS6_EEE4baseEv
   0.54%  nmos-cpp-registry          [.] _ZNKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE5beginEv
   0.53%  libc-2.27.so               [.] __strlen_avx2

Support SDP creation/processing for remaining modes of RTP operation specified by IS-05

IS-05 documentation on Interpretation of SDP Files describes 7 modes of operation. A few of these are not yet implemented by nmos-cpp. If you are interested in FEC, SMPTE 2022-7 Temporal Redundancy, or RTCP, help would be welcome.

nmos-cpp-node accepts IS-05 PATCH request with "" transport_file results in 200 SUCCESS

I ran into this strange edge case: I had to chase down a bug in my code because empty transport_file data injected by my code was causing exceptions in the JSON parser. When I use empty data via the API, on the other hand, nmos-cpp-node thinks everything's fine, going so far as to report back the zero-length SDP:

The request:

curl -H 'Content-Type: application/json' -H 'Accept: application/json' -X PATCH http://d13:3215/x-nmos/connection/v1.0/single/receivers/1e6ee63a-3d30-5788-b0c2-07e97d77e375/staged -d '{"activation":{"mode":"activate_immediate"},"master_enable":true, "sender_id":"855c19a5-5ee8-5c7b-86b3-6d1f4b7f70d8","transport_file":{"data": "", "type":"application/sdp"}}'

The response;

{"activation":{"activation_time":"1551397926:995761753","mode":"activate_immediate","requested_time":null},"master_enable":true,"sender_id":"855c19a5-5ee8-5c7b-86b3-6d1f4b7f70d8","transport_file":{"data":"","type":"application/sdp"},"transport_params":[{"destination_port":"auto","interface_ip":"auto","multicast_ip":null,"rtp_enabled":true,"source_ip":null},{"destination_port":"auto","interface_ip":"auto","multicast_ip":null,"rtp_enabled":true,"source_ip":null}]}

Virtual NMOS device?

Hi, first of all thankyou for your develpment!

I'm trying to build a ST2110 lab to test NMOS and I'm finding difficult to test due to the lack of NMOS Devices.
I've been able to generate ST2110 streams with Gstreamer and consume them with SDPs but NMOS seems to be more difficult.

Do you know any way to create Virtual NMOS End points or generators in order to do some tests?

Thanks in advance.
Agustin.

network_types::IN collides with Windows IN macro

While the example implementation does not include the windows headers which define IN, a node implementation very well might and it can be very difficult to work around.

Changing the IN in sdp/json.h to something like INTERNET would avoid all this and doesn't seem to be harder to use.

registry with 1.3, subscriptions query is empty

With the registry that supports 1.3-dev, doing a query in a browser (e.g. chrome) like http://192.168.87.26:3211/x-nmos/query/v1.3/subscriptions returns []. (i.e. no subscriptions are found). If the v1.3 is changed to v1.2, then 5 subscriptions are returned.

Given that the 1.3 is still under development, is this to be expected?

I ask because I think the Fox Dirty Hands workshop is planning to use the newest sony registry. It seems like if there is an app doing 1.3 queries, then it might not be happy.

nmos-cpp-registry spends a lot of time in regex code

When running continuous registry updates from my node, I see the following in "perf top"

   4.47%  nmos-cpp-registry          [.] _ZZNKSt8__detail15_BracketMatcherINSt7__cxx1112regex_traitsIcEELb0ELb0EE8_M_applyEcSt17integral_constantIbLb0EEENKUlvE_clEv
   3.20%  libc-2.27.so               [.] cfree@GLIBC_2.2.5
   3.14%  libstdc++.so.6.0.25        [.] __dynamic_cast
   2.62%  libstdc++.so.6.0.25        [.] _ZNK10__cxxabiv121__vmi_class_type_info12__do_dyncastElNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE
   1.84%  libstdc++.so.6.0.25        [.] _ZNKSt7__cxx117collateIcE12do_transformEPKcS3_
   1.84%  libc-2.27.so               [.] malloc
   1.54%  libc-2.27.so               [.] __GI___strcmp_ssse3
   1.36%  nmos-cpp-registry          [.] _ZNSt6vectorIcSaIcEE4dataEv

Repeatedly breaking on the BracketMatcher function show two principal contributors. The biggest one is the JSON validator, which appears to be recompiling its regexps at run time, possibly because the it's rebuilding the registration API frequently(?!):

[sorry about the long comments, but I haven't had any luck attaching files to github tickets]

#0  std::__detail::_BracketMatcher<std::__cxx11::regex_traits<char>, false, false>::_M_apply (this=0x7fffdd7ddd20, __ch=-125 '\203') at /usr/include/c++/7/bits/regex_compiler.tcc:612
#1  0x0000555555742164 in std::__detail::_BracketMatcher<std::__cxx11::regex_traits<char>, false, false>::_M_make_cache (this=0x7fffdd7ddd20) at /usr/include/c++/7/bits/regex_compiler.h:556
#2  0x000055555573dc61 in std::__detail::_BracketMatcher<std::__cxx11::regex_traits<char>, false, false>::_M_ready (this=0x7fffdd7ddd20) at /usr/include/c++/7/bits/regex_compiler.h:525
#3  0x000055555573e969 in std::__detail::_Compiler<std::__cxx11::regex_traits<char> >::_M_insert_bracket_matcher<false, false> (this=0x7fffdd7de190, __neg=true) at /usr/include/c++/7/bits/regex_compiler.tcc:444
#4  0x000055555573ad67 in std::__detail::_Compiler<std::__cxx11::regex_traits<char> >::_M_bracket_expression (this=0x7fffdd7de190) at /usr/include/c++/7/bits/regex_compiler.tcc:363
#5  0x0000555555735e79 in std::__detail::_Compiler<std::__cxx11::regex_traits<char> >::_M_atom (this=0x7fffdd7de190) at /usr/include/c++/7/bits/regex_compiler.tcc:349
#6  0x0000555555732999 in std::__detail::_Compiler<std::__cxx11::regex_traits<char> >::_M_term (this=0x7fffdd7de190) at /usr/include/c++/7/bits/regex_compiler.tcc:139
#7  0x000055555572fa66 in std::__detail::_Compiler<std::__cxx11::regex_traits<char> >::_M_alternative (this=0x7fffdd7de190) at /usr/include/c++/7/bits/regex_compiler.tcc:121
#8  0x000055555572fa89 in std::__detail::_Compiler<std::__cxx11::regex_traits<char> >::_M_alternative (this=0x7fffdd7de190) at /usr/include/c++/7/bits/regex_compiler.tcc:124
#9  0x000055555572d6d8 in std::__detail::_Compiler<std::__cxx11::regex_traits<char> >::_M_disjunction (this=0x7fffdd7de190) at /usr/include/c++/7/bits/regex_compiler.tcc:97
#10 0x000055555572bb77 in std::__detail::_Compiler<std::__cxx11::regex_traits<char> >::_Compiler (this=0x7fffdd7de190, __b=0x7fff7000c570 "^[^\\s\\/]+\\/[^\\s\\/]+$", __e=0x7fff7000c584 "", __loc=..., __flags=(unknown: 16))
    at /usr/include/c++/7/bits/regex_compiler.tcc:82
#11 0x0000555555729d0c in std::__detail::__compile_nfa<char const*, std::__cxx11::regex_traits<char> > (__first=0x7fff7000c570 "^[^\\s\\/]+\\/[^\\s\\/]+$", __last=0x7fff7000c584 "", __loc=..., __flags=(unknown: 16)) at /usr/include/c++/7/bits/regex_compiler.h:203
#12 0x000055555572728a in std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> >::basic_regex<char const*> (this=0x7fffdd7de4a0, __first=0x7fff7000c570 "^[^\\s\\/]+\\/[^\\s\\/]+$", __last=0x7fff7000c584 "", __loc=..., __f=(unknown: 16))
    at /usr/include/c++/7/bits/regex.h:767
#13 0x00005555557255a7 in std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> >::basic_regex<char const*> (this=0x7fffdd7de4a0, __first=0x7fff7000c570 "^[^\\s\\/]+\\/[^\\s\\/]+$", __last=0x7fff7000c584 "", __f=(unknown: 16))
    at /usr/include/c++/7/bits/regex.h:512
#14 0x00005555557235f1 in std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> >::basic_regex<std::char_traits<char>, std::allocator<char> > (this=0x7fffdd7de4a0, __s="^[^\\s\\/]+\\/[^\\s\\/]+$", __f=(unknown: 16)) at /usr/include/c++/7/bits/regex.h:493
#15 0x00005555559ab8a9 in nlohmann::json_schema_draft4::json_validator::validate_string (this=0x555555f5cbe8, instance=..., schema=..., name="root.data.caps.media_types[1]") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:766
#16 0x00005555559a9160 in nlohmann::json_schema_draft4::json_validator::validate (this=0x555555f5cbe8, instance=..., schema_=..., name="root.data.caps.media_types[1]") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:466
#17 0x00005555559a8e51 in nlohmann::json_schema_draft4::json_validator::validate (this=0x555555f5cbe8, instance=..., schema_=..., name="root.data.caps.media_types[1]") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:438
#18 0x00005555559a9e54 in nlohmann::json_schema_draft4::json_validator::validate_array (this=0x555555f5cbe8, instance=..., schema=..., name="root.data.caps.media_types") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:569
#19 0x00005555559a9137 in nlohmann::json_schema_draft4::json_validator::validate (this=0x555555f5cbe8, instance=..., schema_=..., name="root.data.caps.media_types") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:462
#20 0x00005555559aa699 in nlohmann::json_schema_draft4::json_validator::validate_object (this=0x555555f5cbe8, instance=..., schema=..., name="root.data.caps") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:649
#21 0x00005555559a910e in nlohmann::json_schema_draft4::json_validator::validate (this=0x555555f5cbe8, instance=..., schema_=..., name="root.data.caps") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:458
#22 0x00005555559aa699 in nlohmann::json_schema_draft4::json_validator::validate_object (this=0x555555f5cbe8, instance=..., schema=..., name="root.data") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:649
#23 0x00005555559a910e in nlohmann::json_schema_draft4::json_validator::validate (this=0x555555f5cbe8, instance=..., schema_=..., name="root.data") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:458
#24 0x00005555559a8e51 in nlohmann::json_schema_draft4::json_validator::validate (this=0x555555f5cbe8, instance=..., schema_=..., name="root.data") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:438
#25 0x00005555559a8e51 in nlohmann::json_schema_draft4::json_validator::validate (this=0x555555f5cbe8, instance=..., schema_=..., name="root.data") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:438
#26 0x00005555559aa699 in nlohmann::json_schema_draft4::json_validator::validate_object (this=0x555555f5cbe8, instance=..., schema=..., name="root") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:649
#27 0x00005555559a910e in nlohmann::json_schema_draft4::json_validator::validate (this=0x555555f5cbe8, instance=..., schema_=..., name="root") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:458
#28 0x00005555559a8e51 in nlohmann::json_schema_draft4::json_validator::validate (this=0x555555f5cbe8, instance=..., schema_=..., name="root") at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:438
#29 0x00005555559a86c0 in nlohmann::json_schema_draft4::json_validator::validate (this=0x555555f5cbe8, instance=...) at /home/sable/bt/git/nmos-cpp/Development/third_party/nlohmann/json-validator.cpp:359
#30 0x0000555555946adc in web::json::experimental::details::json_validator_impl::validate (this=0x555555df8f10, value=..., id=...) at /home/sable/bt/git/nmos-cpp/Development/cpprest/json_validator_impl.cpp:115
#31 0x0000555555944c6a in web::json::experimental::json_validator::validate (this=0x555555f53918, value=..., id=...) at /home/sable/bt/git/nmos-cpp/Development/cpprest/json_validator_impl.cpp:137
#32 0x000055555590a1db in nmos::make_unmounted_registration_api(nmos::registry_model&, slog::base_gate&)::{lambda(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)#4}::operator()(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&) const::{lambda(web::json::value)#1}::operator()(web::json)
    (__closure=0x7fff5c003920, body=...) at /home/sable/bt/git/nmos-cpp/Development/nmos/registration_api.cpp:161
#33 0x00005555559139f7 in std::_Function_handler<bool (web::json::value), nmos::make_unmounted_registration_api(nmos::registry_model&, slog::base_gate&)::{lambda(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)#4}::operator()(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&) const::{lambda(web::json::value)#1}>::_M_invoke(std::_Any_data const&, web::json::value&&) (__functor=..., __args#0=...) at /usr/include/c++/7/bits/std_function.h:302
#34 0x00005555558e0e85 in std::function<bool (web::json::value)>::operator()(web::json::value) const (this=0x7fffdd7e18c0, __args#0=...) at /usr/include/c++/7/bits/std_function.h:706
#35 0x00005555559138e3 in pplx::task<web::json::value>::_ContinuationTaskHandle<web::json::value, bool, nmos::make_unmounted_registration_api(nmos::registry_model&, slog::base_gate&)::{lambda(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)#4}::operator()(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&) const::{lambda(web::json::value)#1}, std::integral_constant<bool, false>, pplx::details::_TypeSelectorNoAsync>::_LogWorkItemAndInvokeUserLambda<std::function<bool (web::json::value)>, web::json::value>(std::function<bool (web::json::value)>&&, bool (&&)(web::json::value)) const (this=0x7fff5c009710, _func=..., _value=...) at /usr/local/include/pplx/pplxtasks.h:3859
#36 0x0000555555913719 in pplx::task<web::json::value>::_ContinuationTaskHandle<web::json::value, bool, nmos::make_unmounted_registration_api(nmos::registry_model&, slog::base_gate&)::{lambda(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)#4}::operator()(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&) const::{lambda(web::json::value)#1}, std::integral_constant<bool, false>, pplx::details::_TypeSelectorNoAsync>::_Continue(nmos::make_unmounted_registration_api(nmos::registry_model&, slog::base_gate&)::{lambda(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)#4}::operator()(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&) const::{lambda(web::json::value)#1}, std::integral_constant<bool, false>) const (this=0x7fff5c009710) at /usr/local/include/pplx/pplxtasks.h:3891
#37 0x000055555591357d in pplx::task<web::json::value>::_ContinuationTaskHandle<web::json::value, bool, nmos::make_unmounted_registration_api(nmos::registry_model&, slog::base_gate&)::{lambda(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basi---Type <return> to continue, or q <return> to quit---
c_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)#4}::operator()(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&) const::{lambda(web::json::value)#1}, std::integral_constant<bool, false>, pplx::details::_TypeSelectorNoAsync>::_Perform() const (this=0x7fff5c009710) at /usr/local/include/pplx/pplxtasks.h:3864
#38 0x0000555555913359 in pplx::details::_PPLTaskHandle<bool, pplx::task<web::json::value>::_ContinuationTaskHandle<web::json::value, bool, nmos::make_unmounted_registration_api(nmos::registry_model&, slog::base_gate&)::{lambda(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)#4}::operator()(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&) const::{lambda(web::json::value)#1}, std::integral_constant<bool, false>, pplx::details::_TypeSelectorNoAsync>, pplx::details::_ContinuationTaskHandleBase>::invoke() const (this=0x7fff5c009710)
    at /usr/local/include/pplx/pplxtasks.h:1637
#39 0x000055555571ee68 in pplx::details::_TaskProcHandle::_RunChoreBridge (_Parameter=0x7fff5c009710) at /usr/local/include/pplx/pplx.h:116
#40 0x00007ffff79a51b5 in void boost::_bi::list1<boost::_bi::value<void*> >::operator()<void (*)(void*), boost::_bi::list0>(boost::_bi::type<void>, void (*&)(void*), boost::_bi::list0&, int) () from /usr/local/lib/libcpprest.so.2.10
#41 0x00007ffff79a5150 in boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > >::operator()() () from /usr/local/lib/libcpprest.so.2.10
#42 0x00007ffff79a5103 in void boost::asio::asio_handler_invoke<boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > > >(boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > >&, ...) ()
   from /usr/local/lib/libcpprest.so.2.10
#43 0x00007ffff79a5098 in void boost_asio_handler_invoke_helpers::invoke<boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > >, boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > > >(boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > >&, boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > >&) () from /usr/local/lib/libcpprest.so.2.10
#44 0x00007ffff79a4fc6 in boost::asio::detail::completion_handler<boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) () from /usr/local/lib/libcpprest.so.2.10
#45 0x0000555555759242 in boost::asio::detail::task_io_service_operation::complete (this=0x7fff6001e060, owner=..., ec=..., bytes_transferred=0) at /usr/include/boost/asio/detail/task_io_service_operation.hpp:38
#46 0x000055555575a20f in boost::asio::detail::task_io_service::do_run_one (this=0x555555f49cd0, lock=..., this_thread=..., ec=...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:372
#47 0x0000555555759ebf in boost::asio::detail::task_io_service::run (this=0x555555f49cd0, ec=...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:149
#48 0x000055555575a50c in boost::asio::io_service::run (this=0x7ffff7dd4868 <crossplat::threadpool::shared_instance()::s_shared+8>) at /usr/include/boost/asio/impl/io_service.ipp:59

Runner-up looks to be the user of that API:

#0  std::__detail::_BracketMatcher<std::__cxx11::regex_traits<char>, false, false>::_M_apply (this=0x555555f94900, __ch=49 '1') at /usr/include/c++/7/bits/regex_compiler.h:550
#1  0x0000555555747441 in std::__detail::_BracketMatcher<std::__cxx11::regex_traits<char>, false, false>::operator() (this=0x555555f94900, __ch=49 '1') at /usr/include/c++/7/bits/regex_compiler.h:454
#2  0x00005555557423b0 in std::_Function_handler<bool (char), std::__detail::_BracketMatcher<std::__cxx11::regex_traits<char>, false, false> >::_M_invoke(std::_Any_data const&, char&&) (__functor=..., __args#0=@0x7ffff16277b4: 49 '1')
    at /usr/include/c++/7/bits/std_function.h:302
#3  0x000055555573bfe8 in std::function<bool (char)>::operator()(char) const (this=0x555555f8e2a0, __args#0=49 '1') at /usr/include/c++/7/bits/std_function.h:706
#4  0x0000555555737758 in std::__detail::_State<char>::_M_matches (this=0x555555f8e290, __char=49 '1') at /usr/include/c++/7/bits/regex_automaton.h:170
#5  0x0000555555734349 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=27) at /usr/include/c++/7/bits/regex_executor.tcc:326
#6  0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=27) at /usr/include/c++/7/bits/regex_executor.tcc:480
#7  0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=26) at /usr/include/c++/7/bits/regex_executor.tcc:329
#8  0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=26) at /usr/include/c++/7/bits/regex_executor.tcc:480
#9  0x0000555555734024 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_subexpr_begin (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=25) at /usr/include/c++/7/bits/regex_executor.tcc:254
#10 0x0000555555730e20 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=25) at /usr/include/c++/7/bits/regex_executor.tcc:468
#11 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=24) at /usr/include/c++/7/bits/regex_executor.tcc:329
#12 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=24) at /usr/include/c++/7/bits/regex_executor.tcc:480
#13 0x00005555557340f1 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_subexpr_end (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=23) at /usr/include/c++/7/bits/regex_executor.tcc:269
#14 0x0000555555730e3b in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=23) at /usr/include/c++/7/bits/regex_executor.tcc:470
#15 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=21) at /usr/include/c++/7/bits/regex_executor.tcc:329
#16 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=21) at /usr/include/c++/7/bits/regex_executor.tcc:480
#17 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=20) at /usr/include/c++/7/bits/regex_executor.tcc:329
#18 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=20) at /usr/include/c++/7/bits/regex_executor.tcc:480
#19 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=19) at /usr/include/c++/7/bits/regex_executor.tcc:329
#20 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=19) at /usr/include/c++/7/bits/regex_executor.tcc:480
#21 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_st---Type <return> to continue, or q <return> to quit---
ring<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=18) at /usr/include/c++/7/bits/regex_executor.tcc:329
#22 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=18) at /usr/include/c++/7/bits/regex_executor.tcc:480
#23 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=17) at /usr/include/c++/7/bits/regex_executor.tcc:329
#24 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=17) at /usr/include/c++/7/bits/regex_executor.tcc:480
#25 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=16) at /usr/include/c++/7/bits/regex_executor.tcc:329
#26 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=16) at /usr/include/c++/7/bits/regex_executor.tcc:480
#27 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=15) at /usr/include/c++/7/bits/regex_executor.tcc:329
#28 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=15) at /usr/include/c++/7/bits/regex_executor.tcc:480
#29 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=14) at /usr/include/c++/7/bits/regex_executor.tcc:329
#30 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=14) at /usr/include/c++/7/bits/regex_executor.tcc:480
#31 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=13) at /usr/include/c++/7/bits/regex_executor.tcc:329
#32 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=13) at /usr/include/c++/7/bits/regex_executor.tcc:480
#33 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=12) at /usr/include/c++/7/bits/regex_executor.tcc:329
#34 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=12) at /usr/include/c++/7/bits/regex_executor.tcc:480
#35 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=11) at /usr/include/c++/7/bits/regex_executor.tcc:329
#36 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=11) at /usr/include/c++/7/bits/regex_executor.tcc:480
#37 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=10) at /usr/include/c++/7/bits/regex_executor.tcc:329
#38 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=10) at /usr/include/c++/7/bits/regex_executor.tcc:480
#39 0x0000555555734024 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_subexpr_begin (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=9) at /usr/include/c++/7/bits/regex_executor.tcc:254
---Type <return> to continue, or q <return> to quit---
#40 0x0000555555730e20 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=9) at /usr/include/c++/7/bits/regex_executor.tcc:468
#41 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=8) at /usr/include/c++/7/bits/regex_executor.tcc:329
#42 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=8) at /usr/include/c++/7/bits/regex_executor.tcc:480
#43 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=7) at /usr/include/c++/7/bits/regex_executor.tcc:329
#44 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=7) at /usr/include/c++/7/bits/regex_executor.tcc:480
#45 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=6) at /usr/include/c++/7/bits/regex_executor.tcc:329
#46 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=6) at /usr/include/c++/7/bits/regex_executor.tcc:480
#47 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=5) at /usr/include/c++/7/bits/regex_executor.tcc:329
#48 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=5) at /usr/include/c++/7/bits/regex_executor.tcc:480
#49 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=4) at /usr/include/c++/7/bits/regex_executor.tcc:329
#50 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=4) at /usr/include/c++/7/bits/regex_executor.tcc:480
#51 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=3) at /usr/include/c++/7/bits/regex_executor.tcc:329
#52 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=3) at /usr/include/c++/7/bits/regex_executor.tcc:480
#53 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=2) at /usr/include/c++/7/bits/regex_executor.tcc:329
#54 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=2) at /usr/include/c++/7/bits/regex_executor.tcc:480
#55 0x0000555555734377 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_match (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=1) at /usr/include/c++/7/bits/regex_executor.tcc:329
#56 0x0000555555730ebc in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=1) at /usr/include/c++/7/bits/regex_executor.tcc:480
#57 0x0000555555734024 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_handle_subexpr_begin (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=0) at /usr/include/c++/7/bits/regex_executor.tcc:254
#58 0x0000555555730e20 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11:---Type <return> to continue, or q <return> to quit---
:basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_dfs (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix, __i=0) at /usr/include/c++/7/bits/regex_executor.tcc:468
#59 0x000055555572e893 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_main_dispatch (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix) at /usr/include/c++/7/bits/regex_executor.tcc:87
#60 0x000055555572c955 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_main (this=0x7ffff1628560, 
    __match_mode=std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_Match_mode::_Prefix) at /usr/include/c++/7/bits/regex_executor.h:149
#61 0x000055555572c99d in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_search_from_first (this=0x7ffff1628560) at /usr/include/c++/7/bits/regex_executor.h:101
#62 0x000055555572ab62 in std::__detail::_Executor<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::regex_traits<char>, true>::_M_search (this=0x7ffff1628560) at /usr/include/c++/7/bits/regex_executor.tcc:42
#63 0x0000555555727d5e in std::__detail::__regex_algo_impl<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, char, std::__cxx11::regex_traits<char>, (std::__detail::_RegexExecutorPolicy)0, false> (__s=47 '/', __e=0 '\000', __m=..., __re=..., __flags=(unknown: 64))
    at /usr/include/c++/7/bits/regex.tcc:82
#64 0x0000555555725acf in std::regex_search<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, char, std::__cxx11::regex_traits<char> > (__s=47 '/', __e=0 '\000', __m=..., __re=..., __flags=(unknown: 64)) at /usr/include/c++/7/bits/regex.h:2196
#65 0x00005555557239c4 in std::regex_search<std::char_traits<char>, std::allocator<char>, std::allocator<std::__cxx11::sub_match<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, char, std::__cxx11::regex_traits<char> > (__s="/x-nmos/registration/v1.2/health/nodes/f7699281-695d-5bea-8fb2-b1fba9a57c79", __m=..., __e=..., __f=(unknown: 64)) at /usr/include/c++/7/bits/regex.h:2302
#66 0x000055555571a8ca in web::http::experimental::listener::api_router::route_regex_match (path="/x-nmos/registration/v1.2/health/nodes/f7699281-695d-5bea-8fb2-b1fba9a57c79", route_match=..., route_regex=..., 
    flags=web::http::experimental::listener::api_router::match_prefix) at /home/sable/bt/git/nmos-cpp/Development/cpprest/api_router.cpp:204
#67 0x000055555571974d in web::http::experimental::listener::api_router::operator() (this=0x555555f790c0, req=..., res=..., route_path="", parameters=std::unordered_map with 0 elements, route=
    {flags = web::http::experimental::listener::api_router::match_prefix, route_pattern = {first = {static icase = <optimized out>, static nosubs = <optimized out>, static optimize = <optimized out>, static collate = <optimized out>, static ECMAScript = (unknown: 16), static basic = <optimized out>, static extended = <optimized out>, static awk = <optimized out>, static grep = <optimized out>, static egrep = <optimized out>, _M_flags = (unknown: 16), _M_loc = {static none = 0, static ctype = 1, static numeric = 2, static collate = 4, static time = 8, static monetary = 16, static messages = 32, static all = 63, _M_impl = 0x7ffff6434680, static _S_classic = <optimized out>, static _S_global = <optimized out>, static _S_categories = <optimized out>, static _S_once = <optimized out>, static _S_twinned_facets = <optimized out>}, _M_automaton = std::shared_ptr<const std::__detail::_NFA<std::__cxx11::regex_traits<char> >> (use count 1, weak count 0) = {get() = 0x555555f9a4e0}}, second = std::map with 2 elements = {["api"] = 1, ["version"] = 2}}, method = "", handler = {<std::_Maybe_unary_or_binary_function<pplx::task<bool>, web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&>> = {<No data fields>}, <std::_Function_base> = {static _M_max_size = 16, static _M_max_align = 8, _M_functor = {_M_unused = {_M_object = 0x555555f29900, _M_const_object = 0x555555f29900, _M_function_pointer = 0x555555f29900, _M_member_pointer = (void (std::_Undefined_class::*)(std::_Undefined_class * const)) 0x555555f29900}, _M_pod_data = "\000\231\362UUU\000\000\000\000\000\000\000\000\000"}, _M_manager = 0x555555701dcf <std::_Function_base::_Base_manager<web::http::experimental::listener::api_router>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)>}, _M_invoker = 0x555555701cb2 <std::_Function_handler<pplx::task<bool> (web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&), web::http::experimental::listener::api_router>::_M_invoke(std::_Any_data const&, web::http::http_request&&, web::http::http_response&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)>}})
    at /home/sable/bt/git/nmos-cpp/Development/cpprest/api_router.cpp:72
#68 0x00005555557193fa in web::http::experimental::listener::api_router::operator() (this=0x555555f790c0, req=..., res=..., route_path="", parameters=std::unordered_map with 0 elements) at /home/sable/bt/git/nmos-cpp/Development/cpprest/api_router.cpp:63
#69 0x0000555555701d6c in std::_Function_handler<pplx::task<bool> (web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&), web::http::experimental::listener::api_router>::_M_invoke(std::_Any_data const&, web::http::http_request&&, web::http::http_response&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&) (__functor=..., __args#0=..., 
    __args#1=..., __args#2="", __args#3=std::unordered_map with 0 elements) at /usr/include/c++/7/bits/std_function.h:302
#70 0x0000555555723455 in std::function<pplx::task<bool> (web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)>::operator()(web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&) const (this=0x555555e094c8, __args#0=..., __args#1=..., __args#2="", __args#3=std::unordered_map with 0 elements)
    at /usr/include/c++/7/bits/std_function.h:706
#71 0x0000555555719ef9 in web::http::experimental::listener::api_router::call(std::function<pplx::task<bool> (web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)> const&, std::function<pplx::task<bool> (web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)> const&, web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&) (handler=..., exception_handler=..., req=..., res=..., route_path="", parameters=std::unordered_map with 0 elements)
    at /home/sable/bt/git/nmos-cpp/Development/cpprest/api_router.cpp:116
#72 0x00005555557198df in web::http::experimental::listener::api_router::operator() (this=0x555555e32b28, req=..., res=..., route_path="", parameters=std::unordered_map with 0 elements, route=
    {flags = web::http::experimental::listener::api_router::match_prefix, route_pattern = {first = {static icase = <optimized out>, static nosubs = <optimized out>, static optimize = <optimized out>, static collate = <optimized out>, static ECMAScript = (unknown: 16), static basic = <optimized out>, static extended = <optimized out>, static awk = <optimized out>, static grep = <optimized out>, static egrep = <optimized out>, _M_flags = (unknown: 16), _M_loc = {static none = 0, static ctype = 1, static numeric = 2, static collate = 4, static time = 8, static monetary = 16, static messages = 32, static all = 63, _M_impl = 0x7ffff6434680, static _S_classic = <optimized out>, static _S_global = <optimized out>, static _S_categories = <optimized out>, static _S_once = <optimized out>, static _S_twinned_facets = <optimized out>}, _M_automaton = std::shared_ptr<const std::__detail::_NFA<std::__cxx11::regex_traits<char> >> (use count 1, weak count 0) = {get() = 0x555555f9a620}}, second = std::map with 0 elements}, method = "", handler = {<std::_Maybe_unary_or_binary_function<pplx::task<bool>, web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::all---Type <return> to continue, or q <return> to quit---
ocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&>> = {<No data fields>}, <std::_Function_base> = {static _M_max_size = 16, static _M_max_align = 8, _M_functor = {_M_unused = {_M_object = 0x555555f790c0, _M_const_object = 0x555555f790c0, _M_function_pointer = 0x555555f790c0, _M_member_pointer = (void (std::_Undefined_class::*)(std::_Undefined_class * const)) 0x555555f790c0, this adjustment 140737488345632}, _M_pod_data = "\300\220\367UUU\000\000 \332\377\377\377\177\000"}, _M_manager = 0x555555701dcf <std::_Function_base::_Base_manager<web::http::experimental::listener::api_router>::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)>}, _M_invoker = 0x555555701cb2 <std::_Function_handler<pplx::task<bool> (web::http::http_request, web::http::http_response, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&), web::http::experimental::listener::api_router>::_M_invoke(std::_Any_data const&, web::http::http_request&&, web::http::http_response&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)>}})
    at /home/sable/bt/git/nmos-cpp/Development/cpprest/api_router.cpp:81
#73 0x00005555557193fa in web::http::experimental::listener::api_router::operator() (this=0x555555e32b28, req=..., res=..., route_path="", parameters=std::unordered_map with 0 elements) at /home/sable/bt/git/nmos-cpp/Development/cpprest/api_router.cpp:63
#74 0x000055555571920a in web::http::experimental::listener::api_router::operator() (this=0x555555e32b28, req=...) at /home/sable/bt/git/nmos-cpp/Development/cpprest/api_router.cpp:41
#75 0x0000555555817a6a in std::__invoke_impl<void, web::http::experimental::listener::api_router&, web::http::http_request> (__f=..., __args#0=...) at /usr/include/c++/7/bits/invoke.h:60
#76 0x000055555581636d in std::__invoke<web::http::experimental::listener::api_router&, web::http::http_request> (__fn=..., __args#0=...) at /usr/include/c++/7/bits/invoke.h:95
#77 0x00005555558136af in std::reference_wrapper<web::http::experimental::listener::api_router>::operator()<web::http::http_request> (this=0x555555fce9a0, __args#0=...) at /usr/include/c++/7/bits/refwrap.h:356
#78 0x0000555555810dfb in std::_Function_handler<void (web::http::http_request), std::reference_wrapper<web::http::experimental::listener::api_router> >::_M_invoke(std::_Any_data const&, web::http::http_request&&) (__functor=..., __args#0=...)
    at /usr/include/c++/7/bits/std_function.h:316
#79 0x00007ffff78483cb in std::function<void (web::http::http_request)>::operator()(web::http::http_request) const () from /usr/local/lib/libcpprest.so.2.10
#80 0x00007ffff7846126 in web::http::experimental::listener::details::http_listener_impl::handle_request(web::http::http_request) () from /usr/local/lib/libcpprest.so.2.10
#81 0x00007ffff79f4f51 in (anonymous namespace)::asio_server_connection::dispatch_request_to_listener() () from /usr/local/lib/libcpprest.so.2.10
#82 0x00007ffff79f39a0 in (anonymous namespace)::asio_server_connection::handle_headers() () from /usr/local/lib/libcpprest.so.2.10
#83 0x00007ffff79f2f89 in (anonymous namespace)::asio_server_connection::handle_http_line(boost::system::error_code const&) () from /usr/local/lib/libcpprest.so.2.10
#84 0x00007ffff79f2243 in (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}::operator()(boost::system::error_code const&, unsigned long) const () from /usr/local/lib/libcpprest.so.2.10
#85 0x00007ffff79fa9cb in boost::asio::detail::read_until_match_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}>::operator()(boost::system::error_code const&, unsigned long, int) () from /usr/local/lib/libcpprest.so.2.10
#86 0x00007ffff7a14c32 in boost::asio::detail::binder2<boost::asio::detail::read_until_match_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}>, boost::system::error_code, unsigned long>::operator()() () from /usr/local/lib/libcpprest.so.2.10
#87 0x00007ffff7a1239d in void boost::asio::asio_handler_invoke<boost::asio::detail::binder2<boost::asio::detail::read_until_match_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}>, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2<boost::asio::detail::read_until_match_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}>, boost::system::error_code, unsigned long>&, ...) () from /usr/local/lib/libcpprest.so.2.10
#88 0x00007ffff7a109f4 in void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<boost::asio::detail::read_until_match_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}>, boost::system::error_code, unsigned long>, {lambda(boost::system::error_code const&, unsigned long)#2}>(boost::asio::detail::binder2<boost::asio::detail::read_until_match_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}>, boost::system::error_code, unsigned long>&, {lambda(boost::system::error_code const&, unsigned long)#2}&) ()
   from /usr/local/lib/libcpprest.so.2.10
#89 0x00007ffff7a0e682 in void boost::asio::detail::asio_handler_invoke<boost::asio::detail::binder2<boost::asio::detail::read_until_match_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}>, boost::system::error_code, unsigned long>, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, {lambda(boost::system::error_code const&, unsigned long)#2}>(boost::asio::detail::binder2<boost::asio::detail::read_until_match_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}>, boost::system::error_code, unsigned long>&, boost::asio::detail::read_until_match_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, {lambda(boost::system::error_code const&, unsigned long)#2}>*) () from /usr/local/lib/libcpprest.so.2.10
#90 0x00007ffff7a0bfbe in void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<boost::asio::detail::read_until_match_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}>, boost::system::error_code, unsigned long>, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}>(boost::asio::detail::binder2<boost::asio::detail::read_until_match_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}>, boost::system::error_code, unsigned long>&, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}&) () from /usr/local/lib/libcpprest.so.2.10
#91 0x00007ffff7a09c9d in boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1, boost::asio::detail::read_until_match_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::allocator<char>, (anonymous namespace)::crlfcrlf_nonascii_searcher_t, (anonymous namespace)::asio_server_connection::start_request_response()::{lambda(boost::system::error_code const&, unsigned long)#2}> >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) () from /usr/local/lib/libcpprest.so.2.10
#92 0x0000555555759242 in boost::asio::detail::task_io_service_operation::complete (this=0x7fff7c017430, owner=..., ec=..., bytes_transferred=0) at /usr/include/boost/asio/detail/task_io_service_operation.hpp:38
#93 0x000055555575a20f in boost::asio::detail::task_io_service::do_run_one (this=0x555555f49cd0, lock=..., this_thread=..., ec=...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:372
#94 0x0000555555759ebf in boost::asio::detail::task_io_service::run (this=0x555555f49cd0, ec=...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:149
#95 0x000055555575a50c in boost::asio::io_service::run (this=0x7ffff7dd4868 <crossplat::threadpool::shared_instance()::s_shared+8>) at /usr/include/boost/asio/impl/io_service.ipp:59

Race between new registrations and threads updating the model

I mentioned seeing this problem in Wuppertal -- not all devices are getting registered at start-up, although changing the log level seemed to help. I've been seeing this problem more frequently now and have started trying to investigate it. As best I can tell, there seems to be some sort of strange race between my threads adding things to the model and the thread that registers resources with the RDS.

To quickly summarize my system, my version of nmos-cpp-node has to interact with a server to discover devices and their associated resources to register them. The server typically has four devices (two transmitters and two receivers). Often, what happens is that only the first device to get added to the model, one of the transmitterts gets recorded with the RDS.

However, just to confuse the issue, if I run my software under valgrind (which forces everything to run single-threaded), then I only see one or both of the receivers get registered.

I've manage to work around the problem to some extent: If I delay the call to node_condition.notify_all() until after all four of a server's devices have been added to the model, then all the devices get registered with the RDS. However, if multiple servers get contacted in parallel, then I also have to make sure that the four servers' threads are started at least one second apart to make sure that all of each servers' devices get registered. However, this is all very much papering over the problem -- if events from the server arrive all together (like, say, from a bulk configure request), it's likely that the race will recur and some of the model updates won't make it to the RDS.

I realize this is a rather vague description of the problem, but I haven't any luck reproducing this problem with synthetic device data. If someone can suggest how I might investigate the problem, I'd really appreciate. In particular, I assume that the problem is somewhere in the registered_operation function, although the function looks to me like it has all the necessary locking. I don't fully understand how and where the update time for the grain used to monitor update times come from -- for instance, if that time gets captured when the condition variable is first notified, and then the model gets updated while request_registration is waiting for an HTTP response, could the grain update times somehow off, causing registered_operation to think that updates that occurred during the registration_request call to be considered to have occurred before the registration?

Also, I notice that registered_operation sets most_recent_update twice, once before processing all the events and once afterwards. It seems to me that one of those updates is unnecessary at best and erroneous at worst. Doesn't the second update make it lose any changes to the grain that occurred while requests to the RDS were outstanding?

Thanks,
Bill

Passing bad JSON for command-line settings causes a crash

@datkins47 pointed out passing bad JSON for command-line settings causes a crash.

Unlike code in the APIs implemented in the nmos module itself, nmos-cpp-node/main.cpp (applies to registry too) parses the settings without catching web::json::json_exception. :-(

This should be fixed since it's especially easy to get wrong as passing JSON on the command line is a pain because double-quotes need escaping.

Setting Staged parameters with an SDP with no source-filter does not set multicast address

The attached file is an sdp without a source-filter attribute

sdp_with_no_source_filter.txt

When this sdp is pasted into the staged parameters (using nmos-explorer) the multicast address is not set.

There are comments in nmos/sdp_utils.cpp which might lead one to believe that the multicast address is supposed to be set, but the code is different from the comments.

The line in question is line 652

// media connection data overrides session connection data (if no source filter) if (params[nmos::fields::source_ip].is_null())

The comment says "if no source filter", which is the case for this SDP. But the code says no source_ip which is almost certainly set because of line 589

params[nmos::fields::source_ip] = value::string(sdp::fields::unicast_address(sdp::fields::origin(session_description)));

I think source-filters are highly desired, maybe even considered required, but it is also apparent that not all vendors are supplying them, at least not yet. If no source-filter is present, is it intended to get a multicast-ip like the comments indicate?

cross-compiling nmos-cpp-registry under Linux

At long last, I have a toolchain with which to cross-compile nmos-cpp-node and have run into a strange little problem:

 [exec] [ 66%] Building CXX object CMakeFiles/nmos-cpp-registry.dir/nmos-cpp-registry/main.cpp.o
 [exec] ccache /opt/hlit/cross_x86_64_v8i/gcc6/bin/g++  -DBST_SHARED_MUTEX_BOOST -DCPPREST_FORCE_HTTP_CLIENT_ASIO -DCPPREST_FORCE_HTTP_LISTENER_ASIO -DCPPREST_NO_SSL_LEAK_SUPPRESS -DSLOG_LOGGING_SEVERITY=slog::max_verbosity -DSLOG_STATIC -I/home/bt/git/nmos-cpp/Development -I/home/bt/git/nmos-cpp/Development/third_party -I/home/bt/git/nmos-cpp/Development/sdpxlate -isystem /home/bt/git/nmos-cpp/cpprestsdk-2.10.2-nmos-cpp/install/include -I/home/bt/git/nmos-cpp/Development/../../cpprestsdk-2.10.2-nmos-cpp/Release/libs/websocketpp -isystem /opt/hlit/cross_x86_64_v8i/include -I/home/bt/git/nmos-cpp/Development/third_party/nlohmann -I/usr/include/libxml2  -Wall -Wstrict-aliasing -fstrict-aliasing -Wextra -Wno-unused-parameter -pedantic -Wno-long-long -O3   -std=c++11 -o CMakeFiles/nmos-cpp-registry.dir/nmos-cpp-registry/main.cpp.o -c /home/bt/git/nmos-cpp/Development/nmos-cpp-registry/main.cpp
 [exec] In file included from /home/bt/git/nmos-cpp/cpprestsdk-2.10.2-nmos-cpp/install/include/cpprest/ws_client.h:30:0,
 [exec]                  from /home/bt/git/nmos-cpp/Development/cpprest/ws_listener.h:9,
 [exec]                  from /home/bt/git/nmos-cpp/Development/nmos-cpp-registry/main.cpp:3:
 [exec] /home/bt/git/nmos-cpp/cpprestsdk-2.10.2-nmos-cpp/install/include/cpprest/ws_msg.h: In member function 'void web::websockets::client::websocket_outgoing_message::set_utf8_message(const istream&)':
 [exec] /home/bt/git/nmos-cpp/cpprestsdk-2.10.2-nmos-cpp/install/include/cpprest/ws_msg.h:100:36: error: 'SIZE_MAX' was not declared in this scope
 [exec]          this->set_message(istream, SIZE_MAX, websocket_message_type::text_message);
 [exec]                                     ^~~~~~~~

I don't understand how this can possibly be the case: ws_client.h indirectly includes stdint.h, which is where SIZE_MAX is defined. I have verified this both by inspection and by using strace(1) to track calls to open(2). The toolchain is using glibc 2.17 and gcc 4.9.2.

Any bright ideas on how I might fix or at least diagnose this problem?

As a workaround, is there a straightforward way to skip building nmos-cpp-registry? Just building -node would be sufficient to get me going.

nmos-cpp-mode "is04_versions" setting does not affect DNS-SD advertisements

I'm trying out the latest code (to test those SDP parser changes) and noticed the is04_versions setting (I thought I would use it for now because I'm not sure what changes I would need to make to support v1.3 correctly). I notice that the mDNS advertisements for _nmos-node._tcp still claim the api_ver supports v1.2 even though I specified '"is04_versions": ["v1.0", "v1.1"]' on the command line. The HTTP interface correctly reflect the versions as exposed at /x-nmos/node/. Furthermore, the advertisements don't reflect that v1.3 is available if I omit the setting.

Document how logging can be configured

Related to #14, logging is worth a specific paragraph or two in the documentation (or porting the internal slog documentation to GitHub...).

In particular:

  • compile-time logging level configuration
  • run-time logging level configuration
  • explanation of the slog::severities (e.g. "too much info", what the heck is that?)
  • nmos-cpp settings for "error_log" and "access_log" files, as well as "logging_level"

Thank you, @datkins47.

nmos-cpp-registry emits "error: -65537 while registering advertisement" when setting "domain" on command line

I've included the complete chatter below. I assume this is essentially a cosmetic bug, and that the registration shouldn't succeed because it doesn't end in "local".

On the up side, there are no multicast DNS-SD registrations when I run it this way, which was what I was trying to accomplish. Yay!

$ uname -a
Linux sable 4.15.0-45-generic #48-Ubuntu SMP Tue Jan 29 16:28:13 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ nmos-cpp-registry '{"settings_address": "127.0.0.1", "domain": "binkie", "logging_level": 11}' 
2019-02-27 22:26:03.988: info: 140643596077056: Starting nmos-cpp registry
*** WARNING *** The program 'nmos-cpp-registry' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/blog/projects/avahi-compat.html>
2019-02-27 22:26:04.180: error: 140643217086208: DNSServiceRegister reported error: -65537 while registering advertisement for: nmos-cpp_query_192-168-1-15:3211._nmos-query._tcp.binkie
2019-02-27 22:26:04.184: error: 140643208693504: DNSServiceRegister reported error: -65537 while registering advertisement for: nmos-cpp_registration_192-168-1-15:3210._nmos-registration._tcp.binkie
2019-02-27 22:26:04.188: error: 140643200300800: DNSServiceRegister reported error: -65537 while registering advertisement for: nmos-cpp_registration_192-168-1-15:3210._nmos-register._tcp.binkie
2019-02-27 22:26:04.193: error: 140643191908096: DNSServiceRegister reported error: -65537 while registering advertisement for: nmos-cpp_node_192-168-1-15:3212._nmos-node._tcp.binkie
2019-02-27 22:26:04.196: error: 140643183515392: DNSServiceRegister reported error: -65537 while registering advertisement for: nmos-cpp_system_192-168-1-15:10641._nmos-system._tcp.binkie

Trouble parsing SDP a=fmtp line that has extra whitespace

Report from @billt-hlit of a small corner case in the SDP parser refusing to find the sampling parameter in the fmtp attribute.

a=fmtp:96  sampling=YCbCr-4:2:2; width=1280; height=720; exactframerate=50; depth=10; TCS=SDR; colorimetry=BT709; PM=2110GPM; TP=2110TPW; SSN=ST2110-20:2017

See the problem? It took me a while to realize that the parser was failing because there were two spaces in from of "sampling", not just one.

Is this SDP attribute compliant? It's really hard to be sure. The grammar in RFC 4566 says

; sub-rules of 'a='
   attribute =           (att-field ":" att-value) / att-field
 
   att-field =           token
 
   att-value =           byte-string

so it has no opinion on how anything after the colon should be formatted. Its description of the fmtp attribute is ambiguous:

a=fmtp:<format> <format specific parameters>

Is that whitespace between the ">" and the "<" required to be a single space? I don't think this is a formal grammar at this point in the RFC. Finally, the SDP description in 2110-20 standard seems to be relatively clear on this point: "the section shall consist of a sequence of media type parameter entries, each followed by a semicolon (“;”) character followed by whitespace". But then we get vague: "a = pair, with no whitespace within the name or value or between the name, equal sign, and value". So, whitespace in front of the name isn't obviously forbidden, although such a name would have to appear first in a video fmtp attribute for it to be truly part of the name -- and that's an weirdly literal interpretation of the standard.

There's a beautiful symmetry to this: We had that discussion about the trailing space on this fmtp line in Wuppertal. Maybe you can have a discussion about leading spaces in Newbury. :o)

@garethsb-sony note: I'm informed that this at least is being made to follow convention in the ST2110 one-year review, so that it won't require a trailing ';', let alone the space.

Aside from that, if it is [isn't?] compliant, should we care, or should the parser be a bit more forgiving of whitespace in the fmtp attribute?

Also, a comment regarding logging: It took me a while to track down this problem, simply because I was looking at the wrong SDP when trying to figure out what was wrong. It's not clear to me how the code might be changed to include the offending fmtp line in the exception, if that's even possible, but that would have reduced my debugging time a fair amount.

mDNSResponder doesn't support unicast DNS-SD on Linux

I'm trying to get unicast DNS-SD set up (thanks for the examples on the wiki, Gareth) and have run into an ugly tight loop in nmos-cpp-node. If I run the command

nmos-cpp-node '{"logging_level":-2,  "domain": "undefined.local"}'

I get hammered with error messages like

2019-01-02 20:55:04.162: warning: 140737013049088: Did not discover a suitable Registration API via DNS-SD
2019-01-02 20:55:04.162: info: 140737013049088: Attempting discovery of a Registration API
2019-01-02 20:55:04.162: error: 140737080190720: DNSServiceBrowse reported error: -65540
2019-01-02 20:55:04.162: warning: 140737013049088: Did not discover a suitable Registration API via DNS-SD
2019-01-02 20:55:04.162: info: 140737013049088: Attempting discovery of a Registration API
2019-01-02 20:55:04.162: error: 140737281615616: DNSServiceBrowse reported error: -65540

Built on Linux using gcc 6.2 and glibc < 2.18 and running mDNSresponder 878.70.2.

Trailing / missing in connection API "href" entry in IS-04 controls

Some controller at the Houston interop wasn't adding a slash at the end of the URL we expose. That's the URL's fault, as I read IS-05 sections 2.0 and 3.1.

Easy fix:

commit 747fc8cb86a63641afd9f9be49590e5e7497c322
Author: Bill Trost <[email protected]>
Date:   Thu Feb 21 10:38:32 2019 -0800

    nmos::make_device was omitting the trailing slash required by the IS-05 control entry

diff --git Development/nmos/node_resources.cpp Development/nmos/node_resources.cpp
index aeb1813..9327edf 100644
--- Development/nmos/node_resources.cpp
+++ Development/nmos/node_resources.cpp
@@ -44,7 +44,7 @@ namespace nmos
             auto connection_uri = web::uri_builder()
                 .set_scheme(U("http"))
                 .set_port(nmos::fields::connection_port(settings))
-                .set_path(U("/x-nmos/connection/") + make_api_version(version));
+                .set_path(U("/x-nmos/connection/") + make_api_version(version) + U("/"));
             auto type = U("urn:x-nmos:control:sr-ctrl/") + make_api_version(version);
 
             for (const auto& host_address : host_addresses)

sdp connection info outside of media description not handled correctly

In sdp_utils.cpp in get_session_description_sdp_parameters where the Connection Data is handled after the Time Descriptions, the code assumes that the connection_data, if there is any, is an array. Unfortunately, if there is connection data outside the media descriptions, it is stored as an object instead of an array and the connection_data.at(0) causes an exception. If the code is changed to access it as an object, the exception is avoided. (i.e. just changed connection_data.at(0) to connection_data)

Sample SDP: (note that the c= is not in a specific media description.)

v=0
o=- 16119794021444559877 16119794021444559877 IN IP4 192.168.87.25
s=wnip:BL07S01:Blade07c:7.0.0.1
i=BL07S01 : Blade07c
c=IN IP4 239.192.195.69/255
t=0 0
m=audio 50100 RTP/AVP 100
a=recvonly
a=rtpmap:100 L24/48000/2
a=fmtp:100 channel-order=SMPTE2110.(ST);
a=ptime:0.25
a=ts-refclk:ptp=IEEE1588-2008:00-00-00-00-00-00-00-00:4
a=mediaclk:direct=0

test-nmos-is0405 fails IS-04 test 10 when nmos-cpp-node uses avahi

Hi, everyone,

I've been doing development guided by the test-nmos-is0405 script Riedel has shared, and the trunk (as of 91750507f34) fails IS-04 test 10, "Node advertises a Node type mDNS announcement with no ver_* TXT records in the presence of a Registration API", at least when test-nmos-is0405 is built using avahi. The error message from the test is "No matching mdns announcement found for node."

I've looked at it with the DNS-SD browser provided by avahi, and the records are very strange. nmos-cpp_node_ip-address:port is displayed in the browser, but when I select it, the only thing the browser eventually shows is a "timeout reached" message. By comparison, the RDS shows a DNS record with a bunch of information, including a couple of TXT records.

Has anyone else run these tests against nmos-cpp-node? Do you see the same behavior, and are you running avahi or mdnsbridge?

Thanks,
Bill

Foo_Bar is not a valid hostname

nmos-cpp-registry rejects node registrations with "Foo_Bar is not a valid hostname", when the value contains an underscore.

This is due to this code, which rejects the underscore:

else if (format == "hostname")
{
// see https://stackoverflow.com/a/106223
bst::regex re(R"(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*)");
if (!bst::regex_match(value, re))
throw std::invalid_argument(value + " is not a valid hostname");
}

That implementation was based on https://stackoverflow.com/a/106223, which quotes RFC1123 and RFC952.

However, the accepted answer to https://stackoverflow.com/questions/2180465/can-domain-name-subdomains-have-an-underscore-in-it quotes RFC2181, which does allow underscores in domain names.

So, we need to understand what "hostname" is actually intended to mean!

Thanks to @billt-hlit for discovering this issue.

Compilation completed, but fails nmos-cpp-registry-test

Please bear in mind I'm installing this into a docker conatiner with a base of Ubuntu 16.04. Compilation is now complete but after running nmos-cpp-registry-test from build directory I get alerted to failed tests. All packages are installed into /home. Looks related to MDNS. I have installed "mDNSResponder-878.30.4" and ran the following:

cd /home/mDNSResponder*/mDNSPosix
set HAVE_IPV6=0
make os=linux
make os=linux install

Packages installed to get compilation to work are:

RUN apt-get update && apt-get install -y --no-install-recommends
g++ build-essential openssl libssl-dev && rm -rf /var/lib/apt/lists/*

Output from nmos-cpp-registry-test:

root@ubuntu:/home/nmos-cpp/Development/build# ./nmos-cpp-registry-test

nmos-cpp-registry-test is a Catch v1.10.0 host application.
Run with -? for options

-------------------------------------------------------------------------------
testMdnsAdvertiseAPIs
-------------------------------------------------------------------------------
/home/nmos-cpp/Development/mdns/test/mdns_test.cpp:91
...............................................................................

/home/nmos-cpp/Development/mdns/test/mdns_test.cpp:117: FAILED:
  CATCH_REQUIRE( gate.hasLogMessage("Advertisement started for 3 service(s)") )
with expansion:
  false

-------------------------------------------------------------------------------
testMdnsBrowseAPIs
-------------------------------------------------------------------------------
/home/nmos-cpp/Development/mdns/test/mdns_test.cpp:127
...............................................................................

/home/nmos-cpp/Development/mdns/test/mdns_test.cpp:153: FAILED:
  CATCH_REQUIRE( gate.hasLogMessage("Advertisement started for 3 service(s)") )
with expansion:
  false

-------------------------------------------------------------------------------
testMdnsResolveAPIs
-------------------------------------------------------------------------------
/home/nmos-cpp/Development/mdns/test/mdns_test.cpp:199
...............................................................................

/home/nmos-cpp/Development/mdns/test/mdns_test.cpp:228: FAILED:
  CATCH_REQUIRE( gate.hasLogMessage("Advertisement started for 1 service(s)") )
with expansion:
  false

===============================================================================
test cases:  29 |  26 passed | 3 failed
assertions: 225 | 222 passed | 3 failed

root@ubuntu:/home/nmos-cpp/Development/build#

Finally I've pushed the Dockerfile/Makefile to my Github if you'd like to take a look: https://github.com/rhastie/docker-nmos-cpp. The Dockerfile should show you the build process I'm trying to automate.

Any help appreciated
Thanks,

Add the Linux build instructions for nmos-cpp itself

Reminder to me that we need to add the Linux-specific build instructions/examples for nmos-cpp itself (including sensible cmake options) in the Getting Started documentation, and also @simonlo-sony's cross-compilation build instructions targeting e.g. a Raspberry Pi.

Node behaviour after 4xx errors from the Registration API

During the Wuppertal interop, one user questioned the intended behaviour after the node received a 4xx from the Registration API.

I’ve checked the implementation and run some tests; in the case of receiving a 4xx status code in response to the initial node resource registration, the node behaviour code treats this like a connection failure/server error and performs exponential backoff.

After a successful initial registration, during registered operation, the behaviour changes. In this case, 4xx errors are (logged, and) effectively ignored. This means that the node, and as many of its sub-resources as possible persist in the registry, although the state of some sub-resources will be out-of-sync (or they might not be found in the registry at all). This means that, as per the spec, the same registration request is not resubmitted. However, subsequent changes to the resource will be retried. (There are a lot of comments regarding handling of different categories of status codes in the node behaviour code. See handle_registration_error_conditions in nmos/node_behaviour.cpp.)

What we could argue is missing is logic to not bother submitting registration requests for resources whose super-resource wasn’t successfully registered. But given that this case is much less likely in a production environment, I’m not convinced that is worth doing.

Perhaps documentation here or informative documentation with the IS-04 spec would be worthwhile...

Problems with updating node registrations

I started using node-cpp-registry instead of the BBC's registry and am running into problems with node reregistrations not working. In short, I get a "409 Conflict" error when I try to update the node's registration.

I'll attach detailed logs of some sample changes I made to the node's main.cpp to demonstrate the problem and the output of both the node and the registry. I didn't have this problem when working against the BBC registry in Wuppertal last month.

Any suggestions? I'm not able to use the BBC registry here because I can't run it on the machine that the node is running on, and can't get the registry to be exposed to the LAN.

build failure with gcc 6.3 and boost 1.62

Commit ca4aca5 introduced a build problem under Debian 4.9:

/home/hbv-bld1/bt/git/nmos-cpp/Development/cpprest/ws_listener_impl.cpp:227:103: error: no match for 'operator==' (operand types are 'boost::system::error_code' and 'std::error_code')
if (make_error_code(boost::asio::error::address_family_not_supported) == ec
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
In file included from /usr/include/boost/asio/io_service.hpp:25:0,
from /usr/include/boost/asio/basic_io_object.hpp:19,
from /usr/include/boost/asio/basic_waitable_timer.hpp:20,
from /usr/include/boost/asio/steady_timer.hpp:30,
from /usr/include/websocketpp/common/asio.hpp:61,
from /usr/include/websocketpp/transport/asio/base.hpp:31,
from /usr/include/websocketpp/transport/asio/connection.hpp:31,
from /usr/include/websocketpp/transport/asio/endpoint.hpp:32,
from /usr/include/websocketpp/config/asio_no_tls.hpp:32,
from /home/hbv-bld1/bt/git/nmos-cpp/Development/cpprest/ws_listener_impl.cpp:18:

...and similarly for the other two comparisons in that expression. I tried simply casting the LHS to the RHS's type and vice-versa, but gcc didn't like the casts.

Details:

  • Linux hbv-bld1 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64 GNU/Linux
  • gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)
  • BOOST_LIB_VERSION "1_62"
  • Built with "cmake .. -D'BUILD_SHARED_LIBS'='0'"

Access to current registration service in use

In JT-NM TR-1001, section 10.2.6, it indicates:

Media Nodes should, through product-specific means, provide a status parameter indicating which registration service is currently in use.

The registration service in use is reported from the node_behaviour_thread. Is there a way outside of this thread to get the registration service currently in use? If so, what is it? If not, should there be?

CMAKE Error when compiling - enum chroma_subsampling

Hi, trying to build in Ubuntu 16.04 from the latest commit I get the following error:

Scanning dependencies of target nmos-cpp-node
[ 88%] Building CXX object CMakeFiles/nmos-cpp-node.dir/nmos-cpp-node/main.cpp.o
In file included from /home/ubuntu/Downloads/sony/nmos-cpp/Development/nmos-cpp-node/main.cpp:10:0:
/home/ubuntu/Downloads/sony/nmos-cpp/Development/nmos/node_resources.h:17:10: error: use of enum ‘chroma_subsampling’ without previous declaration
enum chroma_subsampling;
^
In file included from /home/ubuntu/Downloads/sony/nmos-cpp/Development/nmos-cpp-node/main.cpp:10:0:
/home/ubuntu/Downloads/sony/nmos-cpp/Development/nmos/node_resources.h:45:343: error: ‘chroma_subsampling’ has not been declared
space, const nmos::transfer_characteristic& transfer_characteristic, chroma_subs
^
CMakeFiles/nmos-cpp-node.dir/build.make:62: recipe for target 'CMakeFiles/nmos-cpp-node.dir/nmos-cpp-node/main.cpp.o' failed
make[2]: *** [CMakeFiles/nmos-cpp-node.dir/nmos-cpp-node/main.cpp.o] Error 1
CMakeFiles/Makefile2:222: recipe for target 'CMakeFiles/nmos-cpp-node.dir/all' failed
make[1]: *** [CMakeFiles/nmos-cpp-node.dir/all] Error 2
Makefile:94: recipe for target 'all' failed
make: *** [all] Error 2

Adding #include "nmos/components.h to node_resources.h seems to fix the complie error.

Hope this help.
Agustin.

Cmake error for nmos-cpp under Ubuntu16.04(Virtualbox and Vagrant)

I think I have completed set-up of all dependencies successfully(C++ REST SDK, Boost C++, mdns etc). However, the result of cmake of nmos-cpp was failure. That is error message.

vagrant@vagrant:~/nmos-cpp/Development/build$ cmake -DCMAKE_BUILD_TYPE:STRING="Release" -DWERROR:BOOL="0" -DWEBSOCKETPP_INCLUDE_DIR=$HOME/cpprestsdk-2.10.2-nmos-cpp/Release/libs/websocketpp -DBOOST_INCLUDEDIR:PATH="$HOME/boost_1_67_0" -DBOOST_LIBRARYDIR:PATH="$HOME/boost_1_67_0/lib" -DCPPREST_INCLUDE_DIR:PATH="$HOME/cpprestsdk-2.10.2-nmos-cpp/" ..

CMake Error at /home/vagrant/cpprestsdk-2.10.2-nmos-cpp/Release/build/src/cpprestsdk-config.cmake:17 (include):
include could not find load file:

/home/vagrant/cpprestsdk-2.10.2-nmos-cpp/Release/build/src/cpprestsdk-targets.cmake

Call Stack (most recent call first):
CMakeLists.txt:33 (find_package)

-- Found cpprestsdk
CMake Error at CMakeLists.txt:37 (get_target_property):
get_target_property() called with non-existent target
"cpprestsdk::cpprest".

-- Using configured websocketpp include directory at /home/vagrant/cpprestsdk-2.10.2-nmos-cpp/Release/libs/websocketpp
-- Boost version: 1.67.0
-- Found the following Boost libraries:
-- system
-- date_time
-- regex
-- thread
-- chrono
-- atomic
-- Configuring incomplete, errors occurred!
See also "/home/vagrant/nmos-cpp/Development/build/CMakeFiles/CMakeOutput.log".
See also "/home/vagrant/nmos-cpp/Development/build/CMakeFiles/CMakeError.log".

I think that cause of the error is maybe not existing of [cpprestsdk-config.cmake] in [/home/vagrant/cpprestsdk-2.10.2-nmos-cpp/Release/build/src/].
But I can't conceive how to solve this error.

Broken Linux build: `kDNSServiceErr_Timeout` constant is not defined in Avahi compatibility layer

Value of sender_id in staged parameters of receiver after processing an SDP, should it be null?

In https://raw.githubusercontent.com/AMWA-TV/nmos-device-connection-management/v1.0.x/APIs/schemas/v1.0-receiver-stage-schema.json the description for sender_id indicates that the sender_id should be null if the receiver has not been configured to receive anything or if it is receiving from a non-NMOS sender.

Does this mean that when using the nmos-explorer to paste an SDP into a receiver, it should be assumed that the SDP is for a non-NMOS sender and that the sender_id should be set to null? (Maybe somewhere in handle_connection_resource_patch() in nmos/connection_api.cpp)

Errors while registering advertisement

Hello,
I'm trying to build a container for the nmos-cpp-registry and I'm facing problems while advertising the services.
They could not be found using avahi-browse and I see the following lines in the stdout:

...
2019-02-25 14:13:16.613: error: 140539986867968: DNSServiceRegister reported error: -65563 while registering advertisement for: nmos-cpp_query_10-129-4-108:3211._nmos-query._tcp
2019-02-25 14:13:19.614: error: 140539978475264: DNSServiceRegister reported error: -65563 while registering advertisement for: nmos-cpp_registration_10-129-4-108:3210._nmos-registration._tcp
2019-02-25 14:13:22.616: error: 140539970082560: DNSServiceRegister reported error: -65563 while registering advertisement for: nmos-cpp_registration_10-129-4-108:3210._nmos-register._tcp
2019-02-25 14:13:25.617: error: 140539961689856: DNSServiceRegister reported error: -65563 while registering advertisement for: nmos-cpp_node_10-129-4-108:3212._nmos-node._tcp
...

I'm running the container with these options:

docker run -P --network host --name NMOS-REGISTRY sony-nmos-registry

The image itself (derived from an Ubuntu 18.10) is built using these packages:

From Ubuntu repositories:

  • libboost-chrono1.67.0
  • libboost-date-time1.67.0
  • libboost-regex1.67.0
  • libboost-system1.67.0
  • libboost-thread1.67.0
  • libboost-atomic1.67.0
  • libboost-filesystem1.67.0
  • libboost-random1.67.0
  • libboost-serialization1.67.0

From source:

  • github microsoft/cpprestsdk v2.10.8
  • Apple mDNSResponder 878.30.4
  • your patch "poll-rather-than-select.patch"
  • and this repo (branch master)

I really don't know where to look at to find a way to make it working as expected, the same procedure outside a container is working like a charm.

I can publish the Dockerfile if needed.

Do you have any advise?

nmos-cpp-registry does not handle host_addresses or host_address options/settings as indicated in comments of main.cpp

The comments in nmos-cpp-registry/main.cpp around line 78 indicate that if the host_addresses setting was omitted, then add all the interface_addresses. The actual code does not check to see if the host_addresses is in the settings. Instead, it just unconditionally uses all the interface_addresses.

Similarly for host_address except that the actual code checks to see if host_addresses is present instead of checking to see if host_address is not present.

The effect is that adding the host_address or host_addresses settings to the command line does not really do what you were wishing for.

The current code looks like:

    // if the "host_addresses" setting was omitted, add all the interface addresses
    const auto interface_addresses = web::http::experimental::interface_addresses();
    if (!interface_addresses.empty())
    {
        web::json::insert(registry_model.settings, std::make_pair(nmos::fields::host_addresses, web::json::value_from_elements(interface_addresses)));
    }

    // if the "host_address" setting was omitted, use the first of the "host_addresses"
    if (registry_model.settings.has_field(nmos::fields::host_addresses))
    {
        web::json::insert(registry_model.settings, std::make_pair(nmos::fields::host_address, nmos::fields::host_addresses(registry_model.settings)[0]));
    }

And should probably look like:

    // if the "host_addresses" setting was omitted, add all the interface addresses
    if (registry_model.settings.has_field(nmos::fields::host_addresses) == false)
    {
        const auto interface_addresses = web::http::experimental::interface_addresses();
        if (!interface_addresses.empty())
        {
            web::json::insert(registry_model.settings, std::make_pair(nmos::fields::host_addresses, web::json::value_from_elements(interface_addresses)));
        }
    }

    // if the "host_address" setting was omitted, use the first of the "host_addresses"
    if (registry_model.settings.has_field(nmos::fields::host_address) == false)
    {
        web::json::insert(registry_model.settings, std::make_pair(nmos::fields::host_address, nmos::fields::host_addresses(registry_model.settings)[0]));
    }

Compilation issue with "sdp_test" in nmos-cpp-registry-test right now

This previously worked fine. Build fails at CMakeFiles/nmos-cpp-registry-test.dir/sdp/test/sdp_test.cpp.o with latest commit (specifically d6e9c49).

I've re-checked the dependencies and nothings seems to have changed. My detailed output from Docker Build is below:

Step 7/10 : RUN mkdir /home/nmos-cpp/Development/build && cd /home/nmos-cpp/Development/build && cmake -G "Unix Makefiles" -DCMAKE_CONFIGURATION_TYPES:STRING="Debug;Release" -DBoost_USE_STATIC_LIBS:BOOL="1" -DBOOST_INCLUDEDIR:PATH="/home/boost_1_67_0" -DBOOST_LIBRARYDIR:PATH="/home/boost_1_67_0/x64/lib" -DWEBSOCKETPP_INCLUDE_DIR:PATH="/home/cpprestsdk-2.10.2-nmos-cpp/Release/libs/websocketpp" -DCPPREST_INCLUDE_DIR:PATH="/home/cpprestsdk-2.10.2-nmos-cpp/" -build /home/nmos-cpp/Development/build .. && make
---> Running in 20f9f7a5d33f
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.8")
-- Found OpenSSL: /usr/lib/x86_64-linux-gnu/libcrypto.so (found version "1.0.2g")
-- Found cpprestsdk
-- Using configured websocketpp include directory at /home/cpprestsdk-2.10.2-nmos-cpp/Release/libs/websocketpp
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Boost version: 1.67.0
-- Found the following Boost libraries:
-- system
-- date_time
-- regex
-- thread
-- chrono
-- atomic
-- Configuring done
-- Generating done
CMake Warning:
Manually-specified variables were not used by the project:

CMAKE_CONFIGURATION_TYPES

-- Build files have been written to: /home/nmos-cpp/Development/build
Scanning dependencies of target mdns_static
[ 1%] Building CXX object CMakeFiles/mdns_static.dir/mdns/core.cpp.o
[ 1%] Building CXX object CMakeFiles/mdns_static.dir/mdns/dns_sd_impl.cpp.o
[ 2%] Building CXX object CMakeFiles/mdns_static.dir/mdns/service_advertiser_impl.cpp.o
[ 2%] Building CXX object CMakeFiles/mdns_static.dir/mdns/service_discovery_impl.cpp.o
/home/nmos-cpp/Development/mdns/service_discovery_impl.cpp: In function 'bool mdns_details::getaddrinfo(const address_handler&, const string&, uint32_t, const duration&, DNSServiceCancellationToken, slog::base_gate&)':
/home/nmos-cpp/Development/mdns/service_discovery_impl.cpp:345:14: warning: unused variable 'more_coming' [-Wunused-variable]
bool more_coming = true;
^
[ 3%] Linking CXX static library libmdns_static.a
[ 3%] Built target mdns_static
Scanning dependencies of target nmos-cpp-registry-test
[ 3%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/nmos-cpp-registry/test/main.cpp.o
[ 4%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/cpprest/api_router.cpp.o
[ 4%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/cpprest/host_utils.cpp.o
[ 5%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/cpprest/http_utils.cpp.o
[ 5%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/cpprest/json_utils.cpp.o
[ 6%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/cpprest/test/api_router_test.cpp.o
[ 6%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/cpprest/test/http_utils_test.cpp.o
[ 7%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/cpprest/test/json_utils_test.cpp.o
[ 7%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/cpprest/test/regex_utils_test.cpp.o
[ 8%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/mdns/test/core_test.cpp.o
[ 8%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/mdns/test/mdns_test.cpp.o
[ 9%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/nmos/api_utils.cpp.o
[ 9%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/nmos/test/api_utils_test.cpp.o
[ 10%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/nmos/test/paging_utils_test.cpp.o
[ 10%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/sdp/sdp_grammar.cpp.o
[ 11%] Building CXX object CMakeFiles/nmos-cpp-registry-test.dir/sdp/test/sdp_test.cpp.o
/home/nmos-cpp/Development/sdp/test/sdp_test.cpp:97:40: warning: integer constant is so large that it is unsigned
{ sdp::fields::session_id, 16088568667046861077 },
^
/home/nmos-cpp/Development/sdp/test/sdp_test.cpp:98:45: warning: integer constant is so large that it is unsigned
{ sdp::fields::session_version, 16088568667046861078 },
^
/home/nmos-cpp/Development/sdp/test/sdp_test.cpp: In function 'void ____C_A_T_C_H____T_E_S_T____0()':
/home/nmos-cpp/Development/sdp/test/sdp_test.cpp:102:22: error: conversion from '__int128' to 'const web::json::details::value_init' is ambiguous
}, keep_order) },
^
In file included from /home/nmos-cpp/Development/sdp/json.h:5:0,
from /home/nmos-cpp/Development/sdp/test/sdp_test.cpp:5:
/home/nmos-cpp/Development/cpprest/json_utils.h:231:30: note: candidate: web::json::details::value_init::value_init(int32_t)
using value::value;
^
/home/nmos-cpp/Development/cpprest/json_utils.h:231:30: note: candidate: web::json::details::value_init::value_init(uint32_t)
/home/nmos-cpp/Development/cpprest/json_utils.h:231:30: note: candidate: web::json::details::value_init::value_init(int64_t)
/home/nmos-cpp/Development/cpprest/json_utils.h:231:30: note: candidate: web::json::details::value_init::value_init(uint64_t)
/home/nmos-cpp/Development/cpprest/json_utils.h:231:30: note: candidate: web::json::details::value_init::value_init(double)
/home/nmos-cpp/Development/cpprest/json_utils.h:237:17: note: candidate: web::json::details::value_init::value_init(bool)
value_init(bool b) : value(b) {}
^
In file included from /usr/include/c++/5/bits/stl_algobase.h:64:0,
from /usr/include/c++/5/memory:62,
from /usr/local/include/cpprest/json.h:18,
from /home/nmos-cpp/Development/sdp/sdp.h:4,
from /home/nmos-cpp/Development/sdp/test/sdp_test.cpp:2:
/usr/include/c++/5/bits/stl_pair.h:133:12: note: initializing argument 2 of 'constexpr std::pair<_T1, _T2>::pair(_U1&&, const _T2&) [with _U1 = const web::json::field&; = void; _T1 = std::__cxx11::basic_string; _T2 = web::json::details::value_init]'
constexpr pair(_U1&& __x, const _T2& __y)
^
/home/nmos-cpp/Development/sdp/test/sdp_test.cpp:250:18: error: no matching function for call to 'value_of(, const bool&)'
}, keep_order);
^
In file included from /home/nmos-cpp/Development/sdp/json.h:5:0,
from /home/nmos-cpp/Development/sdp/test/sdp_test.cpp:5:
/home/nmos-cpp/Development/cpprest/json_utils.h:245:33: note: candidate: web::json::value web::json::value_of(std::initializer_list<std::pair<std::__cxx11::basic_string, web::json::details::value_init> >, bool)
inline web::json::value value_of(std::initializer_list<std::pair<utility::string_t, web::json::details::value_init>> fields, bool keep_order = false)
^
/home/nmos-cpp/Development/cpprest/json_utils.h:245:33: note: no known conversion for argument 1 from '' to 'std::initializer_list<std::pair<std::__cxx11::basic_string, web::json::details::value_init> >'
/home/nmos-cpp/Development/cpprest/json_utils.h:259:33: note: candidate: template web::json::value web::json::value_of(std::initializer_listweb::json::details::value_init)
inline web::json::value value_of(std::initializer_listweb::json::details::value_init elements)
^
/home/nmos-cpp/Development/cpprest/json_utils.h:259:33: note: template argument deduction/substitution failed:
/home/nmos-cpp/Development/sdp/test/sdp_test.cpp:250:18: note: cannot convert '{{sdp::fields::protocol_version, 0}, {sdp::fields::origin, }, {sdp::fields::session_name, "Example Sender 1 (Video)"}, {sdp::fields::time_descriptions, web::json::value_of(std::initializer_listweb::json::details::value_init) with = void}, {sdp::fields::attributes, web::json::value_of(std::initializer_listweb::json::details::value_init) with = void}, {sdp::fields::media_descriptions, web::json::value_of(std::initializer_listweb::json::details::value_init) with = void}}' (type '') to type 'std::initializer_listweb::json::details::value_init'
}, keep_order);
^
make[2]: *** [CMakeFiles/nmos-cpp-registry-test.dir/sdp/test/sdp_test.cpp.o] Error 1
make[1]: *** [CMakeFiles/nmos-cpp-registry-test.dir/all] Error 2
make: *** [all] Error 2
CMakeFiles/nmos-cpp-registry-test.dir/build.make:257: recipe for target 'CMakeFiles/nmos-cpp-registry-test.dir/sdp/test/sdp_test.cpp.o' failed
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/nmos-cpp-registry-test.dir/all' failed
Makefile:94: recipe for target 'all' failed
The command '/bin/sh -c mkdir /home/nmos-cpp/Development/build && cd /home/nmos-cpp/Development/build && cmake -G "Unix Makefiles" -DCMAKE_CONFIGURATION_TYPES:STRING="Debug;Release" -DBoost_USE_STATIC_LIBS:BOOL="1" -DBOOST_INCLUDEDIR:PATH="/home/boost_1_67_0" -DBOOST_LIBRARYDIR:PATH="/home/boost_1_67_0/x64/lib" -DWEBSOCKETPP_INCLUDE_DIR:PATH="/home/cpprestsdk-2.10.2-nmos-cpp/Release/libs/websocketpp" -DCPPREST_INCLUDE_DIR:PATH="/home/cpprestsdk-2.10.2-nmos-cpp/" -build /home/nmos-cpp/Development/build .. && make' returned a non-zero code: 2
Makefile:9: recipe for target 'build' failed
make: *** [build] Error 2

Compilation under Ubuntu Docker

I've followed all the dependencies and successfully compiled the C++ REST SDK under cmake and gcc (quite a few warnings however).

I've now got to compiling the nmos-cpp and successfully ran cmake but under make I get the following error at approx 50%

/home/nmos-cpp/Development/cpprest/ws_listener_impl.cpp:17:47: fatal error: websocketpp/config/boost_config.hpp: No such file or directory
compilation terminated.
CMakeFiles/nmos-cpp-registry.dir/build.make:127: recipe for target 'CMakeFiles/nmos-cpp-registry.dir/cpprest/ws_listener_impl.cpp.o' failed
make[2]: *** [CMakeFiles/nmos-cpp-registry.dir/cpprest/ws_listener_impl.cpp.o] Error 1
CMakeFiles/Makefile2:141: recipe for target 'CMakeFiles/nmos-cpp-registry.dir/all' failed
make[1]: *** [CMakeFiles/nmos-cpp-registry.dir/all] Error 2
Makefile:94: recipe for target 'all' failed
make: *** [all] Error 2
root@ubuntu:/home/nmos-cpp/Development/build#

My cmake file is:

cmake
-G "Unix Makefiles"
-DCMAKE_CONFIGURATION_TYPES:STRING="Debug;Release"
-DBoost_USE_STATIC_LIBS:BOOL="1"
-DBOOST_INCLUDEDIR:PATH="/home/boost_1_67_0"
-DBOOST_LIBRARYDIR:PATH="./home/boost_1_67_0/x64/lib"
-DWEBSOCKETPP_INCLUDE_DIR:PATH="/home/nmos-cpp/Release/libs/websocketpp"
-DCPPREST_INCLUDE_DIR:PATH="/home/cpprestsdk-2.10.2-nmos-cpp/"
-build /home/nmos-cpp/Development/build ..

I believe I'm correctly referencing the boost directories but any assistance on this compilation would be gratefully received

prevent nmos-cpp-registry to create a node

Hi,

when the nmos-cpp-registry starts, it also instantiate an NMOS IS-04 Node.
Is there a way (a flag) to prevent it and just start the query and registration services?

Thanks

Syslog support?

Is there an example of using slog to log via syslog? The current sample programs log to ostreams.

websocket++ library required, contrary to dependencies.md

Hi, Gareth,

According to Dependencies.md, "A copy of the header-only WebSocket++ v0.5.1 is included in the C++ REST SDK, so a separate installation is not necessary." However, the nmos-cpp CMakeLists.txt searches for a websocketpp-config.cmake, so cmake fails if the development library is not present. For example, on my 32-bit Ubuntu 16.04 system, I see:

: [xenial32]bt@hobbes:git/nmos-cpp/Development/build; sudo apt remove libwebsocketpp-dev
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Package 'libwebsocketpp-dev' is not installed, so not removed
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
: [xenial32]bt@hobbes:git/nmos-cpp/Development/build; /home/bt/.local/bin/cmake  ..
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found ZLIB: /usr/lib/i386-linux-gnu/libz.so (found version "1.2.8") 
-- Found OpenSSL: /usr/lib/i386-linux-gnu/libcrypto.so (found version "1.0.2g") 
-- Found cpprestsdk
CMake Error at CMakeLists.txt:44 (find_package):
  By not providing "Findwebsocketpp.cmake" in CMAKE_MODULE_PATH this project
  has asked CMake to find a package configuration file provided by
  "websocketpp", but CMake did not find one.

  Could not find a package configuration file provided by "websocketpp"
  (requested version 0.5.1) with any of the following names:

    websocketppConfig.cmake
    websocketpp-config.cmake

  Add the installation prefix of "websocketpp" to CMAKE_PREFIX_PATH or set
  "websocketpp_DIR" to a directory containing one of the above files.  If
  "websocketpp" provides a separate development package or SDK, be sure it
  has been installed.


-- Configuring incomplete, errors occurred!

I'm hoping the cmake files can be fixed, as I rather avoid the websocket++ dependency.

Thanks,
Bill

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.