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

一、背景描述


某系列产品中,不同产品、国家和地区支持不同的配置项(但差异不大)。各配置项均由其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 }

后续若增加其他产品、国家和地区,需要不断增加文件或扩展函数。此外,各名单的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 //… …

因此,可将产品掩码定义为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

国家掩码定义为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 }

具体掩码结构如下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);

其中,第一列为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)!\n", 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 }

四、总结说明


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

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

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

 

采用掩码方式简化产品国家地区支持能力的表示,布布扣,bubuko.com

时间: 05-16

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

大企业总部和分部采用何种方式组网

随着企业的规模不断扩展,业务分支和办公服务地点覆盖全国,甚至向全球发展.这就要求企业组织要及时的更新和优化自己的网络规划以便能够高效的管理企业,促进企业信息化建设,提高自己企业的核心竞争力,那么企业总部与分部之间如何组网呢?采用什么方式的组网解决方案更适合呢? 企业VPN组网意义: 企业VPN组网主要帮企业组建自己的专属网络,包括本地和跨区域的企业专网,可以满足企业ERP.邮件.服务器.数据传输.电话会议和视频会议等需求,特别是对延时比较敏感的应用,组建企业专网是最优先的解决方法. 企业VPN组

语言(文化)代码与国家地区对照表

// 取得用户默认信息 NSUserDefaults *defaults = [ NSUserDefaults standardUserDefaults]; // 取得 iPhone 支持的所有语言设置 NSArray *languages = [defaults objectForKey : @"AppleLanguages" ]; NSLog (@"%@", languages); // 获得当前iPhone使用的语言 NSString* currentLang

Entity Framework后台采用分页方式取数据与AspNetPager控件的使用

转载至:http://www.cnblogs.com/jaxu/p/3655582.html 本文是一个对AspNetPager控件使用的笔记! 有关AspNetPager控件可以查看杨涛主页.这是一个开放的自定义ASP.NET控件,支持各种自定义的数据分页方式,使用很方便,而且功能也很强大,网站开发过程中使用该控件可以省去很多不必要的麻烦. 本页下载:AspNetPager745DLL.zip 然后看一下在页面上如何通过Entity Framework将分页数据传递给该控件以实现真分页. 页面

VMware虚拟机采用桥接方式不能上网——都是共享神盾惹的祸!

宿主机是XP,双网卡,一个连接互联网,另一个连接内部生产网,通过来回拔插网线,来切换不同的网络(不允许同时连接两个网络).连接互联网的网卡是Realtek RTL8169,IP是192.168.1.88,通过宽带路由器上网.在VMware Workstation8上建了两个虚拟机,一个是XP,一个Linux.虚拟机采用nat或Host-Only+共享Internet连接时,都能上网,但采用桥接方式确不能上网.测试结果如下表(如不能完全显示,请下载附件后直接打开): Vmware网络 宿主机 虚拟

不同的国家/地区与语言缩写代码

发表于 2017-06-29 |  分类于 其他|  1|  阅读次数 346 国家/地区 语言代码 国家地区 语言代码 简体中文(中国) zh-cn 简体中文(台湾地区) zh-tw 繁体中文(香港) zh-hk 英语(香港) en-hk 英语(美国) en-us 英语(英国) en-gb 英语(全球) en-ww 英语(加拿大) en-ca 英语(澳大利亚) en-au 英语(爱尔兰) en-ie 英语(芬兰) en-fi 芬兰语(芬兰) fi-fi 英语(丹麦) en-dk 丹麦语(丹麦)

STM32的串口采用DMA方式接收数据测试(转)

STM32的串口采用DMA方式接收数据测试 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.   参考链接:http://www.amobbs.com/forum.PHP?mod=viewthread&tid=5511863&highlight=dma%E6%8E%A5%E6%94%B6   环境: 主机:WINXP 开发环境:MDK4.23 MCU:STM32F103CBT6 说明: 串口可以配置成用DMA的方式接收数据,不过DMA需要定长才

Android 采用post方式提交数据到服务器

接着上篇<Android 采用get方式提交数据到服务器>,本文来实现采用post方式提交数据到服务器 首先对比一下get方式和post方式: 修改布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="m

MyEclipse10.0 采用插件方式安装 SVN

一.到官方上下载svn1.8.3,下载后的文件名叫site-1.8.3.zip 地址:http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240 这里有很多版本,请自己选择合适的: 二.解压,删除解压后得到的文件中除了名叫features 和plugins 的两个文件夹以外的其他所有文件. 方法1: a) 在MyEclipse10.0 的安装目录中自己新建一个文件夹(我的叫MyPlugins)然后把解压并删除过文件

主机win7,VMware中debian6采用NET方式上网

很久以前就是net方式上网,最近重装虚拟机后上不去网了,弄了半天才成功,必须记下来免得以后又忘了 以下是网上找的方法,但是第2步不需要 原文地址http://www.cnblogs.com/sophine/archive/2012/04/26/2471227.html 1.现在安装好的虚拟机中设置网络连接为 NAT 2.在WIN7电脑的本地连接中设置如下:(不需求这步,跳过) 3.在VMware Nerwrk Adapter VMnet8  中设置IP 为192.168.137.1 (这个ip