diff options
| author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-08-16 16:37:38 +0200 | 
|---|---|---|
| committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-08-16 16:37:38 +0200 | 
| commit | d57f046c40e716069d37f9e6b7911afd41c7b116 (patch) | |
| tree | fd7cec78dd7fd8c3e195aab2a3a01c9525fd37bb /src | |
| parent | 76bd144a8bbedfceceeb9ad2975a3d3f9436e311 (diff) | |
| download | dabmux-d57f046c40e716069d37f9e6b7911afd41c7b116.tar.gz dabmux-d57f046c40e716069d37f9e6b7911afd41c7b116.tar.bz2 dabmux-d57f046c40e716069d37f9e6b7911afd41c7b116.zip  | |
Add support for sending empty linkage sets to clear receiver databases
Diffstat (limited to 'src')
| -rw-r--r-- | src/ConfigParser.cpp | 82 | ||||
| -rw-r--r-- | src/MuxElements.cpp | 43 | ||||
| -rw-r--r-- | src/fig/FIG0_6.cpp | 18 | 
3 files changed, 83 insertions, 60 deletions
diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index d484787..f51eb03 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -102,61 +102,65 @@ static void parse_linkage(ptree& pt,              bool active = pt_set.get("active", true);              bool hard = pt_set.get("hard", true);              bool international = pt_set.get("international", false); -              string service_uid = pt_set.get("keyservice", ""); -            if (service_uid.empty()) { -                etiLog.level(error) << "Key Service for linking set " << -                    setuid << " invalid or missing"; -                throw runtime_error("Invalid service linking definition"); -            }              auto linkageset = make_shared<LinkageSet>(setuid, lsn, active, hard, international);              linkageset->keyservice = service_uid; // TODO check if it exists              auto pt_list = pt_set.get_child_optional("list"); -            if (not pt_list) { -                etiLog.level(error) << "list missing in linking set " << -                    setuid; -                throw runtime_error("Invalid service linking definition"); -            } -            for (const auto& it : *pt_list) { -                const string linkuid = it.first; -                const ptree pt_link = it.second; - -                ServiceLink link; - -                string link_type = pt_link.get("type", ""); -                if (link_type == "dab") link.type = ServiceLinkType::DAB; -                else if (link_type == "fm") link.type = ServiceLinkType::FM; -                else if (link_type == "drm") link.type = ServiceLinkType::DRM; -                else if (link_type == "amss") link.type = ServiceLinkType::AMSS; -                else { -                    etiLog.level(error) << "Invalid type " << link_type << -                        " for link " << linkuid; +            if (service_uid.empty()) { +                if (pt_list) { +                    etiLog.level(error) << "list defined but no keyservice in linking set " << +                        setuid;                      throw runtime_error("Invalid service linking definition");                  } - -                link.id = hexparse(pt_link.get("id", "0")); -                if (link.id == 0) { -                    etiLog.level(error) << "id for link " << -                        linkuid << " invalid or missing"; +            } +            else { +                if (not pt_list) { +                    etiLog.level(error) << "list missing in linking set " << +                        setuid;                      throw runtime_error("Invalid service linking definition");                  } -                if (international) { -                    link.ecc = hexparse(pt_link.get("ecc", "0")); -                    if (link.ecc == 0) { -                        etiLog.level(error) << "ecc for link " << +                for (const auto& it : *pt_list) { +                    const string linkuid = it.first; +                    const ptree pt_link = it.second; + +                    ServiceLink link; + +                    string link_type = pt_link.get("type", ""); +                    if (link_type == "dab") link.type = ServiceLinkType::DAB; +                    else if (link_type == "fm") link.type = ServiceLinkType::FM; +                    else if (link_type == "drm") link.type = ServiceLinkType::DRM; +                    else if (link_type == "amss") link.type = ServiceLinkType::AMSS; +                    else { +                        etiLog.level(error) << "Invalid type " << link_type << +                            " for link " << linkuid; +                        throw runtime_error("Invalid service linking definition"); +                    } + +                    link.id = hexparse(pt_link.get("id", "0")); +                    if (link.id == 0) { +                        etiLog.level(error) << "id for link " <<                              linkuid << " invalid or missing";                          throw runtime_error("Invalid service linking definition");                      } -                } -                else { -                    link.ecc = 0; -                } -                linkageset->id_list.push_back(link); +                    if (international) { +                        link.ecc = hexparse(pt_link.get("ecc", "0")); +                        if (link.ecc == 0) { +                            etiLog.level(error) << "ecc for link " << +                                linkuid << " invalid or missing"; +                            throw runtime_error("Invalid service linking definition"); +                        } +                    } +                    else { +                        link.ecc = 0; +                    } + +                    linkageset->id_list.push_back(link); +                }              }              ensemble->linkagesets.push_back(linkageset);          } diff --git a/src/MuxElements.cpp b/src/MuxElements.cpp index e19c93d..9c1fc7a 100644 --- a/src/MuxElements.cpp +++ b/src/MuxElements.cpp @@ -665,26 +665,35 @@ bool dabEnsemble::validate_linkage_sets()  {      for (const auto& ls : linkagesets) {          const std::string keyserviceuid = ls->keyservice; -        const auto& keyservice = std::find_if( -                services.cbegin(), -                services.cend(), -                [&](const std::shared_ptr<DabService>& srv) { +        if (keyserviceuid.empty()) { +            if (not ls->id_list.empty()) { +                etiLog.log(error, "Linkage set 0x%04x with empty key service " +                        "should have an empty list.", ls->lsn); +                return false; +            } +        } +        else { +            const auto& keyservice = std::find_if( +                    services.cbegin(), +                    services.cend(), +                    [&](const std::shared_ptr<DabService>& srv) {                      return srv->uid == keyserviceuid; -                }); +                    }); -        if (keyservice == services.end()) { -            etiLog.log(error, "Invalid key service %s in linkage set 0x%04x", -                    keyserviceuid.c_str(), ls->lsn); -            return false; -        } +            if (keyservice == services.end()) { +                etiLog.log(error, "Invalid key service %s in linkage set 0x%04x", +                        keyserviceuid.c_str(), ls->lsn); +                return false; +            } -        // need to add key service to num_ids -        const size_t num_ids = 1 + ls->id_list.size(); -        if (num_ids > 0x0F) { -            etiLog.log(error, -                    "Too many links for linkage set 0x%04x", -                    ls->lsn); -            return false; +            // need to add key service to num_ids +            const size_t num_ids = 1 + ls->id_list.size(); +            if (num_ids > 0x0F) { +                etiLog.log(error, +                        "Too many links for linkage set 0x%04x", +                        ls->lsn); +                return false; +            }          }      } diff --git a/src/fig/FIG0_6.cpp b/src/fig/FIG0_6.cpp index b7776f4..8af8ded 100644 --- a/src/fig/FIG0_6.cpp +++ b/src/fig/FIG0_6.cpp @@ -80,8 +80,11 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)          const bool PD = false;          const bool ILS = linkageSetFIG0_6->international; -        // need to add key service to num_ids -        const size_t num_ids = 1 + linkageSetFIG0_6->id_list.size(); +        // need to add key service to num_ids, unless it is empty which means we +        // send a CEI +        const size_t num_ids = linkageSetFIG0_6->keyservice.empty() ? +            // do not transmit list if keyservice empty, it should anyway be empty +            0 : (1 + linkageSetFIG0_6->id_list.size());          if (num_ids > 0x0F) {              etiLog.log(error, @@ -117,7 +120,7 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)          FIGtype0_6 *fig0_6 = (FIGtype0_6*)buf; -        fig0_6->IdListFlag = (num_ids > 0); +        fig0_6->IdListFlag = (num_ids > 0); // C/N=0 and IdListFlag=0 is CEI          fig0_6->LA = linkageSetFIG0_6->active;          fig0_6->SH = linkageSetFIG0_6->hard;          fig0_6->ILS = ILS; @@ -127,6 +130,10 @@ FillStatus FIG0_6::fill(uint8_t *buf, size_t max_size)          buf += sizeof(struct FIGtype0_6);          remaining -= sizeof(struct FIGtype0_6); +        etiLog.log(debug, +                "Linkage set 0x%04x wrote %d", +                linkageSetFIG0_6->lsn, fig0->Length); +          if (num_ids > 0) {              FIGtype0_6_header *header = (FIGtype0_6_header*)buf;              header->rfu = 0; @@ -243,7 +250,10 @@ void FIG0_6::update()      for (const auto& linkageset : m_rti->ensemble->linkagesets) {          const auto lsn = linkageset->lsn; -        for (const auto& link : linkageset->id_list) { +        if (linkageset->keyservice.empty()) { +            linkageSubsets.push_back(*linkageset); +        } +        else for (const auto& link : linkageset->id_list) {              const auto type = link.type;              const auto subset =  | 
