• 采用掩码方式简化产品国家地区支持能力的表示


     

    一、背景描述

         某系列产品中,不同产品、国家和地区支持不同的配置项(但差异不大)。各配置项均由其BranchLeaf结点值(BLV)唯一标识。

         作为ONU通用配置媒介之一,某模块对各配置项创建合法性校验函数IsBranchLeafValid(…),其中包含的结点列表表示产品缺省支持的所有配置项,类似“白名单”;此外根据各国家地区的要求创建屏蔽函数IsBranchLeafScreened (…),其中包含的结点列表表示该国家/地区不予支持的配置项,类似“黑名单”。其中,“黑名单”列表为“白名单”列表的子集。两个名单结合起来对接收到的OLT配置帧进行校验,从而表现出不同的支持能力。

         因此,对于M个产品,N个国家地区,在物理上将需要M+N个黑白名单。具体实现上,黑白名单函数内充斥着大量if...else与switch...case结构:

     1 /* 每个产品对应一个Product_Adapter.c文件,内含IsBranchLeafValid实现 */
     2 BOOL IsBranchLeafValid(OAM_BRANCH_LEAF eBranchLeaf)
     3 {
     4     BOOLEAN retcode = 1;
     5     switch(eBranchLeaf)
     6     {
     7         case OnuSn:
     8         case FirmwareVer:
     9         case ChipsetID:
    10         case EthDSRateLimit:
    11         case QosConfig:
    12         case FastLeaveState:
    13         case FastLeaveCtrl:
    14         case FaxModemConf:
    15         case SIPDigitMap:
    16         //Dozens of eBranchLeaf... ...
    17         {
    18             retcode = 1;
    19         }
    20             break;
    21 
    22         default:
    23         {
    24             retcode = 0;
    25         }
    26             break;
    27     }
    28 
    29     return retcode;
    30 }
    31 
    32 
    33 BOOL IsBranchLeafScreened(INT32U dwdwdwRegionVer, OAM_BRANCH_LEAF eBranchLeaf)
    34 {
    35     if(dwdwRegionVer == DEFAULT_XINJIANG_CFG)
    36     {
    37         switch(eBranchLeaf)
    38         {
    39             case VlanConfig:
    40                 
    41             case FaxModemConf:
    42             case SIPDigitMap:
    43             //Dozens of eBranchLeaf... ...
    44                 return 1;
    45             default:
    46                 return 0;
    47         }
    48     }
    49     else if(dwdwRegionVer == DEFAULT_JIANGSU_CFG)
    50     {
    51        switch(eBranchLeaf)
    52        {
    53             case VlanConfig:
    54               return 1;
    55            default:
    56               return 0;
    57        }           
    58     }
    59     else
    60     {
    61         return 0;
    62     }
    63 }
    View Code

         后续若增加其他产品、国家和地区,需要不断增加文件或扩展函数。此外,各名单的BLV列表内容互有重叠,代码冗余度很高。

    二、改进方案

         定义产品、国家、地区掩码,掩码中各比特表示某BLV的相应产品、国家和地区支持情况。这里将国家和地区分开是为了扩展掩码支持范围。

         例如下面的简化格式(前两比特表示产品支持,后两比特表示地区支持): 

         对于某BLV,上面的0b'1001表示F420V2上海版本支持该配置项,以此类推。

         这样就无需IsBranchLeafScreened和IsBranchLeafValid黑白名单函数,校验时只需根据掩码对应比特(偏移)来判断相应的BLV是否支持。

         对于产品掩码,可在预编译阶段设置掩码偏移值;对于国家和地区,可在ONU启动初始化时通过查询国家地区码来设置掩码偏移值。

     

    三、实践情况

         目前已定义的EPON SFU产品有F420V2/F411V2/F420G/F400G/F1420/F460/F460V2/F460M等等,国家地区码(非指本文“掩码”)如下:

     1 /* 国家码 */
     2 #define DEFAULT_CFG              0    /* 基本默认配置文件 */
     3 #define DEFAULT_RUSSIA_CFG       1    /* 俄罗斯默认配置文件 */
     4 #define DEFAULT_LITHUANIA_CFG    2    /* 立陶宛默认配置文件 */
     5 //… …
     6 
     7 /* 地区码 */
     8 #define DEFAULT_JIANGSU_CFG      200   /* 江苏省默认配置文件 */
     9 #define DEFAULT_XINJIANG_CFG     201   /* 新疆默认配置文件 */
    10 #define DEFAULT_HAINAN_CFG       202   /* 海南默认配置文件 */
    11 #define DEFAULT_TIANJIN_CFG      203   /* 天津默认配置文件 */
    12 #define DEFAULT_ANHUI_CFG        204   /* 安徽默认配置文件 */
    13 #define DEFAULT_SHANGHAI_CFG     205   /* 上海默认配置文件 */
    14 //… …
    View Code

         因此,可将产品掩码定义为1字节,掩码偏移比特定义如下: 

     1 /*ONU产品掩码定义(根据新增产品而扩展)*/
     2 #if defined(CONFIG_CSP_PRODUCT_F411) || defined(CONFIG_CSP_PRODUCT_F420) || defined(CONFIG_CSP_PRODUCT_F420G)
     3     #define PRODUCT_SHIFT            0
     4 #elif defined(CONFIG_CSP_PRODUCT_F400G)
     5     #define PRODUCT_SHIFT            1
     6 #elif defined(CONFIG_CSP_PRODUCT_F1420)
     7     #define PRODUCT_SHIFT            2
     8 #else
     9     #define PRODUCT_SHIFT            3
    10 #endif
    View Code

         国家掩码定义为4字节长整型,从低位到高位依次对应国家码编号,即掩码bit-0表示缺省版本支持情况(恒为1),bit-1表示俄罗斯版本支持情况;地区掩码与国家掩码类似,应注意掩码bit-0恒为1以避免与国家掩码冲突(只能有一个缺省版本),bit-1表示江苏版本支持情况。国家、地区掩码偏移比特定义如下:

    1 VOID GetRegionMask(INT32U dwRegionVer, INT8U *pucNatShift, INT8U *pucRegShift)
    2 {
    3     if(dwRegionVer < DEFAULT_JIANGSU_CFG)
    4         *pucNatShift = dwRegionVer;
    5     else
    6         *pucRegShift = dwRegionVer - 199;
    7 }
    View Code

        具体掩码结构如下OAM_CMD_MAP结构定义如下图所示: 

     1 typedef FUNC_STATUS(*OAM_GET_CMD_HANDLER)(OAM_HEAD_INFO*, INT8U*, INT32U*, CTC_OAM_ACK*);
     2 typedef FUNC_STATUS(*OAM_SET_CMD_HANDLER)(OAM_HEAD_INFO*, INT8U*, INT32U*, CTC_OAM_ACK*);
     3 typedef struct{
     4     OAM_BRANCH_LEAF  eBranchLeaf;
     5     INT8U   ucProductMask;
     6     INT32U  dwNationMask;
     7     INT32U  dwRegionMask;
     8     OAM_GET_CMD_HANDLER  fnGetCmdHandler;
     9     OAM_SET_CMD_HANDLER  fnSetCmdHandler;
    10 }OAM_CMD_MAP;
    11 
    12 #define DEF_8U     0xFF
    13 #define DEF_32U    0xFFFFFFFF
    14 #define GC(NAME)   OAM_##NAME##_Get_Cmd
    15 #define SC(NAME)   OAM_##NAME##_Set_Cmd
    16 
    17 /*OAM命令处理函数映射表 */
    18 OAM_CMD_MAP gOamCmdFuncMap[] = {
    19     {OnuSn,             DEF_8U,   DEF_32U,    DEF_32U,       GC(ONU_SN),            NULL},
    20     {FirmwareVer,       DEF_8U,   DEF_32U,    DEF_32U,       GC(FirmwareVer),       NULL},
    21     {ChipsetID,         DEF_8U,   DEF_32U,    DEF_32U,       GC(ChipsetID),         NULL},
    22     {EthDSRateLimit,    DEF_8U,   DEF_32U,    DEF_32U,       GC(EthDSRateLimit),    SC(EthDSRateLimit)},
    23     {QosConfig,         DEF_8U,   DEF_32U,    DEF_32U,       GC(QosConfig),         SC(QosConfig)},
    24     {FastLeaveState,    DEF_8U,   DEF_32U,    0xFFFFFFBF,    GC(FastLeaveState),    NULL},
    25     {FastLeaveCtrl,     DEF_8U,   DEF_32U,    0xFFFFFFBF,    NULL,                  SC(FastLeaveCtrl)},
    26     {FaxModemConf,      0xFD,     DEF_32U,    0xFFFFFFBD,    GC(FaxModemConf),      SC(FaxModemConf)},
    27     {SIPDigitMap,       0xFD,     DEF_32U,    0xFFFFFFBB,    NULL,                  SC(SIPDigitMap)},
    28     //... ...
    29 };
    30 const INT32U gOamCmdMapNum = sizeof(gOamCmdFuncMap) / sizeof(OAM_CMD_MAP);
    View Code

         其中,第一列为BLV结点值,第2~4列分别为产品、国家、地区掩码,后2列为处理函数指针。 

         例如。BranchLeaf名FaxModemConf对应的地区掩码为0xFFFFFFBD(1...10111101)表示江苏省和上海地区不支持该配置项。产品掩码含义与之类似。校验时黑白名单由下面的函数代替:

     1 BOOL IsBranchLeafSupported(OAM_BRANCH_LEAF eBranchLeaf)
     2 {
     3     INT32U dwMapIdx = 0;
     4     for(dwMapIdx = 0; dwMapIdx < gOamCmdMapNum; dwMapIdx++)
     5     {
     6         if(eBranchLeaf == gOamCmdFuncMap[dwMapIdx].eBranchLeaf)
     7             break;
     8 
     9     }
    10     if(dwMapIdx == gOamCmdMapNum)
    11     {
    12         CtcOamLog(FUNCTION_Oam,"Unknown BranchLeaf(0x%08X)!
    ", eBranchLeaf);
    13         return FALSE;
    14     }
    15     
    16     if(GET_BIT(gOamCmdFuncMap[dwMapIdx].ucProductMask, PRODUCT_SHIFT)  //也可先&&后GET_BIT
    17     && GET_BIT(gOamCmdFuncMap[dwMapIdx].dwNationMask, gdwRegionVer.ucNatShift) 
    18     && GET_BIT(gOamCmdFuncMap[dwMapIdx].dwRegionMask, gdwRegionVer.ucRegShift))
    19         return TRUE;
    20 
    21     return FALSE;   
    22 }
    View Code

    四、总结说明

         1. 采用掩码的表示方法,可极大地消除冗余度和增强扩展性。

         可支持10个产品、32个国家及31个地区的不同配置能力,已支持5个产品、1个国家(缺省)和两个地区,后续新增产品、国家、地区只需要修改掩码值即可,无需增加代码。

         2. 相比原有做法,掩码方式在可读性和易用性方面稍嫌不足,可编写掩码的生成和解析函数或工具予以弥补。

     

  • 相关阅读:
    北航 2012 秋季 软件工程课 M2 要求
    现代软件工程讲义 7 设计阶段 Spec
    软件工程讲义 0 微博上的软件工程
    现代软件工程讲义 8 软件的血型
    北航 2012 秋季 现代软件工程 两人结对 作业要求
    现代软件工程讲义 6 用户调研
    现代软件工程 2012 北航 项目复审模板
    北航 2012 秋季 现代软件工程 团队项目要求
    现代软件工程 学生阅读、思辨和调查作业
    现代软件工程讲义 5 团队合作的阶段
  • 原文地址:https://www.cnblogs.com/clover-toeic/p/3732444.html
Copyright © 2020-2023  润新知