From 0ebce6201e7501b43adc95a394117d1060b3a65e Mon Sep 17 00:00:00 2001
From: "Matthias P. Braendli" <matthias.braendli@mpb.li>
Date: Fri, 1 Aug 2014 12:07:51 +0200
Subject: Refactor protection handling for better readability

---
 src/DabMux.cpp           | 46 +++++++++++++++++++++++-----------------------
 src/MuxElements.cpp      | 17 +++++++++--------
 src/MuxElements.h        | 28 ++++++++++++++++++++++------
 src/ParserCmdline.cpp    | 19 ++++++++++---------
 src/ParserConfigfile.cpp | 12 ++++++------
 src/utils.cpp            | 22 +++++++++-------------
 6 files changed, 79 insertions(+), 65 deletions(-)

(limited to 'src')

diff --git a/src/DabMux.cpp b/src/DabMux.cpp
index 02dadc8..2de18b9 100644
--- a/src/DabMux.cpp
+++ b/src/DabMux.cpp
@@ -157,6 +157,7 @@ static unsigned char Padding_FIB[] = {
 };
 
 
+// Protection levels and bitrates for UEP.
 const unsigned char ProtectionLevelTable[64] = {
     4, 3, 2, 1, 0, 4, 3, 2,
     1, 0, 4, 3, 2, 1, 4, 3,
@@ -168,7 +169,6 @@ const unsigned char ProtectionLevelTable[64] = {
     1, 0, 4, 3, 1, 4, 2, 0
 };
 
-
 const unsigned short BitRateTable[64] = {
     32, 32, 32, 32, 32, 48, 48, 48,
     48, 48, 56, 56, 56, 56, 64, 64,
@@ -471,7 +471,7 @@ int main(int argc, char *argv[])
                     switch ((*subchannel)->type) {
                     case Audio:
                         {
-                            if (protection->form != 0) {
+                            if (protection->form == EEP) {
                                 (*component)->type = 0x3f;  // DAB+
                             }
                         }
@@ -576,14 +576,14 @@ int main(int argc, char *argv[])
             }
             (*subchannel)->bitrate = result;
 
-            if (protection->form == 0) {
-                protection->form = 1;
+            // Use EEP unless we find a UEP configuration
+            if (protection->form == UEP) {
+                protection->form = EEP;
                 for (int i = 0; i < 64; i++) {
-                    if ((*subchannel)->bitrate == BitRateTable[i]) {
-                        if (protection->level == ProtectionLevelTable[i]) {
-                            protection->form = 0;
-                            protection->shortForm.tableIndex = i;
-                        }
+                    if ( (*subchannel)->bitrate == BitRateTable[i] &&
+                         protection->level == ProtectionLevelTable[i] ) {
+                        protection->form = UEP;
+                        protection->uep.tableIndex = i;
                     }
                 }
             }
@@ -775,16 +775,16 @@ int main(int argc, char *argv[])
                 sstc->SCID = (*subchannel)->id;
                 sstc->startAddress_high = (*subchannel)->startAddress / 256;
                 sstc->startAddress_low = (*subchannel)->startAddress % 256;
-                //devrait changer selon le mode de protection desire
-                if (protection->form == 0) {
+                // depends on the desired protection form
+                if (protection->form == UEP) {
                     sstc->TPL = 0x10 |
-                        ProtectionLevelTable[protection->shortForm.tableIndex];
-                } else {
-                    sstc->TPL = 0x20 |
-                        (protection->longForm.option << 2) |
-                        (protection->level);
+                        ProtectionLevelTable[protection->uep.tableIndex];
+                }
+                else if (protection->form == EEP) {
+                    sstc->TPL = 0x20 | (protection->eep.GetOption() << 2) | protection->level;
                 }
-                //Sub-channel Stream Length, multiple of 64 bits 
+
+                // Sub-channel Stream Length, multiple of 64 bits
                 sstc->STL_high = getSizeDWord(*subchannel) / 256;
                 sstc->STL_low = getSizeDWord(*subchannel) % 256;
 
@@ -946,12 +946,12 @@ int main(int argc, char *argv[])
                         ++subchannelFIG0_1) {
                     protection = &(*subchannelFIG0_1)->protection;
 
-                    if (    (protection->form == 0 && figSize > 27) ||
-                            (protection->form != 0 && figSize > 26)) {
+                    if ( (protection->form == UEP && figSize > 27) ||
+                         (protection->form == EEP && figSize > 26) ) {
                         break;
                     }
 
-                    if (protection->form == 0) {
+                    if (protection->form == UEP) {
                         fig0_1subchShort =
                             (FIG_01_SubChannel_ShortF*) &etiFrame[index];
                         fig0_1subchShort->SubChId = (*subchannelFIG0_1)->id;
@@ -964,13 +964,13 @@ int main(int argc, char *argv[])
                         fig0_1subchShort->Short_Long_form = 0;
                         fig0_1subchShort->TableSwitch = 0;
                         fig0_1subchShort->TableIndex =
-                            protection->shortForm.tableIndex;
+                            protection->uep.tableIndex;
 
                         index = index + 3;
                         figSize += 3;
                         figtype0_1->Length += 3;
                     }
-                    else {
+                    else if (protection->form == EEP) {
                         fig0_1subchLong1 =
                             (FIG_01_SubChannel_LongF*) &etiFrame[index];
                         fig0_1subchLong1->SubChId = (*subchannelFIG0_1)->id;
@@ -981,7 +981,7 @@ int main(int argc, char *argv[])
                             (*subchannelFIG0_1)->startAddress % 256;
 
                         fig0_1subchLong1->Short_Long_form = 1;
-                        fig0_1subchLong1->Option = protection->longForm.option;
+                        fig0_1subchLong1->Option = protection->eep.GetOption();
                         fig0_1subchLong1->ProtectionLevel =
                             protection->level;
 
diff --git a/src/MuxElements.cpp b/src/MuxElements.cpp
index 4dd226b..6ecbcf5 100644
--- a/src/MuxElements.cpp
+++ b/src/MuxElements.cpp
@@ -437,14 +437,15 @@ const string dabEnsemble::get_parameter(const string& parameter) const
 
 unsigned short getSizeCu(dabSubchannel* subchannel)
 {
-    if (subchannel->protection.form == 0) {
+    if (subchannel->protection.form == UEP) {
         return Sub_Channel_SizeTable[subchannel->
-            protection.shortForm.tableIndex];
-    } else {
-        dabProtectionLong* protection =
-            &subchannel->protection.longForm;
-        switch (protection->option) {
-        case 0:
+            protection.uep.tableIndex];
+    }
+    else if (subchannel->protection.form == EEP) {
+        dabProtectionEEP* protection =
+            &subchannel->protection.eep;
+        switch (protection->profile) {
+        case EEP_A:
             switch (subchannel->protection.level) {
             case 0:
                 return (subchannel->bitrate * 12) >> 3;
@@ -464,7 +465,7 @@ unsigned short getSizeCu(dabSubchannel* subchannel)
                 return 0;
             }
             break;
-        case 1:
+        case EEP_B:
             switch (subchannel->protection.level) {
             case 0:
                 return (subchannel->bitrate * 27) >> 5;
diff --git a/src/MuxElements.h b/src/MuxElements.h
index 0f9fa18..f1097c0 100644
--- a/src/MuxElements.h
+++ b/src/MuxElements.h
@@ -124,23 +124,39 @@ class dabEnsemble : public RemoteControllable {
 };
 
 
-struct dabProtectionShort {
+struct dabProtectionUEP {
     unsigned char tableSwitch;
     unsigned char tableIndex;
 };
 
+enum dab_protection_eep_profile {
+    EEP_A,
+    EEP_B
+};
+
+struct dabProtectionEEP {
+    dab_protection_eep_profile profile;
 
-struct dabProtectionLong {
-    unsigned char option;
+    // option is a 3-bit field where 000 and 001 are used to
+    // select EEP profile A and B.
+    // Other values are for future use, see
+    // EN 300 401 Clause 6.2.1 "Basic sub-channel organisation"
+    uint8_t GetOption(void) const {
+        return (this->profile == EEP_A) ? 0 : 1;
+    }
 };
 
+enum dab_protection_form_t {
+    UEP, // implies FIG0/1 Short form
+    EEP  //                Long form
+};
 
 struct dabProtection {
     unsigned char level;
-    unsigned char form;
+    dab_protection_form_t form;
     union {
-        dabProtectionShort shortForm;
-        dabProtectionLong longForm;
+        dabProtectionUEP uep;
+        dabProtectionEEP eep;
     };
 };
 
diff --git a/src/ParserCmdline.cpp b/src/ParserCmdline.cpp
index 98140de..9768d20 100644
--- a/src/ParserCmdline.cpp
+++ b/src/ParserCmdline.cpp
@@ -400,14 +400,14 @@ bool parse_cmdline(char **argv,
             (*subchannel)->startAddress = 0;
 
             if (c == 'A') {
-                protection->form = 0;
+                protection->form = UEP;
                 protection->level = 2;
-                protection->shortForm.tableSwitch = 0;
-                protection->shortForm.tableIndex = 0;
+                protection->uep.tableSwitch = 0;
+                protection->uep.tableIndex = 0;
             } else {
+                protection->form = EEP;
                 protection->level = 2;
-                protection->form = 1;
-                protection->longForm.option = 0;
+                protection->eep.profile = EEP_A;
             }
             break;
         case 'L':
@@ -590,17 +590,18 @@ bool parse_cmdline(char **argv,
                 goto EXIT;
             }
             level = strtoul(optarg, NULL, 0) - 1;
-            if (protection->form == 0) {
+            if (protection->form == UEP) {
                 if ((level < 0) || (level > 4)) {
                     etiLog.log(error,
-                            "protection level must be between "
+                            "UEP protection level must be between "
                             "1 to 5 inclusively (current = %i)\n", level);
                     goto EXIT;
                 }
-            } else {
+            }
+            else if (protection->form == EEP) {
                 if ((level < 0) || (level > 3)) {
                     etiLog.log(error,
-                            "protection level must be between "
+                            "EEP protection level must be between "
                             "1 to 4 inclusively (current = %i)\n", level);
                     goto EXIT;
                 }
diff --git a/src/ParserConfigfile.cpp b/src/ParserConfigfile.cpp
index 7a990a3..943e500 100644
--- a/src/ParserConfigfile.cpp
+++ b/src/ParserConfigfile.cpp
@@ -844,14 +844,14 @@ void setup_subchannel_from_ptree(dabSubchannel* subchan,
     subchan->startAddress = 0;
 
     if (type == "audio") {
-        protection->form = 0;
+        protection->form = UEP;
         protection->level = 2;
-        protection->shortForm.tableSwitch = 0;
-        protection->shortForm.tableIndex = 0;
+        protection->uep.tableSwitch = 0;
+        protection->uep.tableIndex = 0;
     } else {
         protection->level = 2;
-        protection->form = 1;
-        protection->longForm.option = 0;
+        protection->form = EEP;
+        protection->eep.profile = EEP_A;
     }
 
     /* Get bitrate */
@@ -938,7 +938,7 @@ void setup_subchannel_from_ptree(dabSubchannel* subchan,
     try {
         int level = pt.get<int>("protection");
 
-        if (protection->form == 0) {
+        if (protection->form == UEP) {
             if ((level < 1) || (level > 5)) {
                 stringstream ss;
                 ss << "Subchannel with uid " << subchanuid <<
diff --git a/src/utils.cpp b/src/utils.cpp
index 4e9d8c3..654759d 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -416,23 +416,19 @@ void printSubchannels(vector<dabSubchannel*>& subchannels)
                 (*subchannel)->id);
         etiLog.log(info, " bitrate:    %i",
                 (*subchannel)->bitrate);
-        if (protection->form == 0) {
+        if (protection->form == UEP) {
             etiLog.log(info, " protection: UEP %i", protection->level + 1);
-        } else {
-            etiLog.log(info, " protection: EEP %i-%c",
-                    protection->level + 1,
-                    protection->longForm.option == 0 ? 'A' : 'B');
-        }
-        if (protection->form == 0) {
-            etiLog.log(info, "  form:      short");
             etiLog.log(info, "  switch:    %i",
-                    protection->shortForm.tableSwitch);
+                    protection->uep.tableSwitch);
             etiLog.log(info, "  index:     %i",
-                    protection->shortForm.tableIndex);
-        } else {
-            etiLog.log(info, "  form:      long");
+                    protection->uep.tableIndex);
+        }
+        else {
+            etiLog.log(info, " protection: EEP %i-%c",
+                    protection->level + 1,
+                    protection->eep.profile == EEP_A ? 'A' : 'B');
             etiLog.log(info, "  option:    %i",
-                    protection->longForm.option);
+                    protection->eep.GetOption());
             etiLog.log(info, "  level:     %i",
                     (*subchannel)->protection.level);
         }
-- 
cgit v1.2.3