**概要:**本节内容描述了MMS-EASE Lite栈组件间的关系。

1 配置文件选项(Profile Options)

“MMS-EASE Lite栈组件”是一种基于不同的OSI协议层的实现。它专门为一些硬件资源非常有限的系统而设计,比如某些嵌入式系统,它具有模块化的特点,以便在实际使用时可以仅仅调用特定应用程序所需的协议层。它由几个C代码模块组成,可以方便地在任何嵌入式系统中编译。除了几个简单的函数(隔离在tp4port.c模块中)以外,MMS-EASE Lite全部使用ANSI标准C文件。在OSI七层参考模型的术语中,每个协议层都被描述为其上层提供“服务”。在本应用中,这些“服务”是通过一系列API来提供的。下图显示了OSI协议层与连接它们的api之间的关系。


2 底层组件移植(Lower Layer Component Portation)

2.1 OSI传输层(TP4)移植

对于新的操作系统或硬件平台,需要移植以下函数:

tp4_init_timer
tp4_check_timer

编译选项的配置:

必选编译选项:-DLEAN_T,功能:编译该版本的TP4 API;

可选编译选项:-DDEBUG_SISCO,功能:使用“slog”启用日志记录

mvl_init_glb_vars

函数名 mvl_init_glb_vars
功能 在TP4初始化过程(tp4_initialize))中被调用,用于初始化定时器服务
函数原型 ST_VOID tp4_init_timer (ST_VOID);
参数
返回值 ST_VOID

tp4_check_timer

函数名 mvl_init_glb_vars
功能 被tp4_event调用。该函数负责监视定时器,每当计时达到1s就调用函数tp4_timer_tick。由sisco提供的tp4_check_timer示例函数适用于大多数系统,但如果目标系统上有更有效的方法,用户也可自由修改该函数。在事件驱动的系统上,重要的是要确保mvl_comm_serve至少每秒钟调用一次,这样这个函数也会被调用。因此,系统休眠时间不应超过1秒。然而,这个限制仅在正在使用TP4服务时生效
函数原型 ST_VOID tp4_init_timer (ST_VOID);
参数
返回值 ST_VOID

2.2 OSI子网络层移植

用户必须提供子网API。更多信息请参阅附录G。

2.3 TCP/IP(via RFC1006)移植

TCP/IP(via RFC1006)协议栈由以下组件组成:

ACSE
OSI演示
OSI对话
TP0(OSI传输层类0)
TCP/IP(由操作系统通过socket提供)

socket接口实现概述

MMS-EASE Lite的sockets接口包含三个任务,每个任务具有阻塞能力(用于等待来自用户或其他任务的消息),如下所示:

Main任务 (每台主机上仅有一个)
Listen任务 (用于监听socket,每台主机上仅有一个)
Read任务 (用于读取socket,每个连接仅有一个)

Main任务包括所有MMS的编解码进程以及用户接口。在启动时,它会生成Listen任务,该任务会监听是否存在被建立的连接。当检测到已建立的连接时,Listen任务向Main任务发送管道消息,Main任务调用" accept "来接收消息,并生成一个Read任务。

如果要进行向外传输的连接,Main任务会执行一个非阻塞连接调用(可参考tp0_sock.c和p_connect_req),然后生成一个Read任务实例,该实例会等待连接完成。

在两种情况(传入或传出)下,当连接完成后,Read任务会接收连接中的包并将它们传递给Main任务。所有连接中的数据包都是由Main任务发送的。

Main任务含有多层函数调用,因此有时很难跟踪用户级函数是如何在最低层实现的。例如,处理传入事件的函数调用层级如下:

main (\mmslite\mvl\usr\server\server.c) 调用  /*主函数*/
mvl_comm_serve (\mmslite\mvl\src\mvl_serv.c) 调用
mvl_net_service (\mmslite\mvl\src\acse\mvl_acse.c) 调用
copp_event (\mmslite\uca\acse\acse2enc.c) 调用
tp0_event (\mmslite\uca\leant\tp0main.c) 调用
np_event (\mmslite\uca\leant\tp0_unix.c)   /*最底层实现*/

通过观察np_event函数的内容我们可以发现,函数开头部分的代码含义是等待来自Read任务(sreadd)或Listen任务(sreadd)的管道消息。

slistend (\mmslite\uca\leant\tp0_list.c)
sreadd (\mmslite\uca\leant\tp0_read.c)

注:任务sreadd和slistend是从MMS-EASE Lite应用程序内部生成的。它们通常位于在mmslite/bin目录中,但默认情况下该目录并不被包含在环境变量中。可以通过将目录/mmslite/bin添加到环境变量中,或者将两个文件复制到被包含在环境变量中的目录(/usr/bin, /usr/local/bin, 或 /bin)下的方式来避免这一问题。当MMS-EASE Lite应用程序出现异常使slistendd任务不能终止时,有时必须使用kill命令手动终止sreadd。

TCP/IP移植

唯一需要移植的是操作系统提供的TCP/IP接口。这段代码已经移植到了一些操作系统中。如果目标操作系统提供以下服务,那么移植移植过程是比较简单的。

TCP/IP的socket接口
多任务和多线程功能
pipe功能

对于大多数移植,应该只需要修改以下四个模块。它们都位于目录\mmslite\uca\leant下:

tp0_sock.c (通用socket代码,Main任务的一部分)
tp0_list.c (Listen任务,适用于UNIX & Win32环境)
tp0_read.c (Read任务,适用于UNIX & Win32环境)
tp0_unix.c (UNIX专用代码,Main任务的一部分)
tp0_w32.c (Win32专用代码,Main任务的一部分)

编译选项

所有用于TCP/IP相关代码都被编译到ositcpe.lib库文件中(Linux系统中为ositcpe.a)。为了在下列库中使能正确的代码,必须使能以下编译选项。

-D LEAN_T
-D MOSI
-D TP0_ENABLED

以下为可选编译选项:

-D S_MT_SUPPORT 使用多线程

3 协议栈配置(Protocol Stack Configuration )

3.1 TCP/IP配置

用户必须填写以下全局结构来配置TCP/IP (viaRFC1006)堆栈:

TP0_CFG tp0_cfg;

其中TP0_CFG的定义如下:

typedef struct{ST_UINT16 max_tpdu_len; /* max len of TPDU. *//* Use to allocate TPDU buffers. */ST_UCHAR max_tpdu_len_enc; /* Binary encoded MAX TPDU len. Computed*//* from max_tpdu_len by tp0_initialize. */ST_UCHAR max_num_conns; /* Max # Connections */ST_BOOLEAN keepalive; /* Use KEEPALIVE option on Sockets. */} TP0_CFG; /* For TP0/RFC1006 only. */

在调用tp0_initialize之前,用户必须设置每个参数。如果在tp0_initialize被调用之后修改该结构体,则修改无效。以下模块提供了一个硬编码的示例:

tp4_hc.c

也可以用osicfg.xml文件来配置。请参阅章节“常用配置问题”。

3.2 OSI传输层(TP4)配置

配置TP4 API时,用户需要填写以下全局结构:

TP_CFG tp_cfg;

其中 TP_CFG的定义如下:

typedef struct{ST_UINT16 max_tpdu_len; /* max len of TPDU. Base on SNPDU size. *//* Use to allocate TPDU buffers. */ST_UCHAR max_tpdu_len_enc; /* Binary encoded MAX TPDU len. Computed*//* from max_tpdu_len by tp4_initialize. */ST_UCHAR max_rem_cdt; /* Max credits we can handle. *//* Will allocate this many TPDU_DT *//* structs. *//* CRITICAL: MUST BE POWER OF 2. */ST_UCHAR loc_cdt; /* CDT value we will ALWAYS send in ACK *//* We only accept in-sequence TPDUs so *//* only purpose of this is to *//* allow peer to send ahead. */ST_UCHAR max_spdu_outst;/* Max # of SPDUs outstanding per conn. *//* Will allocate this many SPDU_INFO *//* structs for transmit queue. *//* CRITICAL: MUST BE POWER OF 2. */ST_UCHAR max_num_conns; /* Max # Connections */ ST_UINT16 window_time; /* Window Time */ST_UINT16 inact_time; /* Inactivity Time */ST_UINT16 retrans_time; /* Retransmission Time */ST_UCHAR max_trans; /* Max # of transmissions of a TPDU */ST_UCHAR ak_delay; /* # of loops to delay sending AK. */} TP_CFG;

在调用tp4_initialize之前,用户必须设置每个参数。如果在tp4_initialize被调用之后修改该结构体,则修改无效。以下模块提供了一个硬编码的示例:

Tp4_hc.c

也可以用osicfg.xml文件来配置。请参阅章节“常用配置问题”。

3.3 OSI网络层(CLNP/ES-IS)配置

配置OSI网络层API时,用户需要填写以下全局结构:

CLNP_PARAM clnp_param;

其中 CLNP_PARAM的定义如下:

typedef struct{ST_UCHAR pdu_lifetime;/* PDU lifetime (in 500 msec units) for *//* outgoing DT PDUs. *//* init to CLNP_DEF_PDU_LIFETIME */ST_UCHAR pdu_lifetime_dec;/* PDU lifetime decrement (1=500msec) *//* for incoming DT or ER PDUs. *//* init to CLNP_DEF_PDU_LIFETIME_DEC */ST_UINT16 esh_cfg_timer;/* How often we report our presence to *//* other network entities (in seconds) *//* init to CLNP_DEF_ESH_CFG_TIMER */ST_UINT16 esh_delay; /* Delay time before first ESH is sent *//* init to CLNP_DEF_ESH_DELAY */ST_UCHAR loc_mac [CLNP_MAX_LEN_MAC];/* Local MAC address *//* For ADLC the NS-USER sets the loc_mac*//* DEBUG: Now the loc_mac has to match *//* the address in adlc.cfg !!! *//* For the Ethernet this param will be *//* read from the driver during init */ST_UCHAR loc_nsap [1+CLNP_MAX_LEN_NSAP];
/* Local len & NSAP address */}CLNP_PARAM;

在调用clnp_init之前,用户必须设置每个参数。如果在clnp_init被调用之后修改该结构体,则修改无效。以下模块提供了一个硬编码的示例:

clnp_hc.c

也可以用osicfg.xml文件来配置。请参阅章节“常用配置问题”。

3.4 网络地址

MMS-EASE Lite中定义了“应用程序引用名称(Application Reference Name)”,缩写为“AR Name”。AR Name是一个最大长度为32字符的ASCII字符串,它用于共同确定应用程序实体信息(AP标题与AE限定符)以及与应用程序相关联的演示地址。换句话说,AR Name并不是两个应用程序通过网络实际进行交换的东西,而是一种更具可读性的ACSE和寻址信息的简写。MMS-EASE Lite应用程序使用AR Name调用MMS连接管理API。

要配置网络地址,用户必须设置以下全局指针来指向DIB_ENTRY数组结构:

DIB_ENTRY *loc_dib_table; 本地地址 (至少有一个)
DIB_ENTRY *rem_dib_table; 远程地址 (根据需求配置)
typedef struct{ST_LONG reserved; /* reserved field */ST_CHAR *name; /* AR Name */ST_CHAR local; /* SD_TRUE if local, SD_FALSE if remote*/ST_UCHAR AP_title_pres; /* present flag */MMS_OBJ_ID AP_title; /* AP title */ST_UCHAR AP_inv_id_pres; /* present flag */ST_INT32 AP_invoke_id; /* AP invocation ID */ST_UCHAR AE_qual_pres; /* present flag */ST_INT32 AE_qual; /* AE qualifier */ST_UCHAR AE_inv_id_pres; /* present flag */ST_INT32 AE_invoke_id; /* AE invocation ID */PRES_ADDR pres_addr; /* Presentation address. */} DIB_ENTRY;

这个DIB_ENTRY定义引用了以下的PRES_ADDR结构:

typedef struct tagPRES_ADDR{int psel_len;char psel [MAX_PSEL_LEN];int ssel_len;char ssel [MAX_SSEL_LEN];ST_INT tp_type; /* Transport Type: TP_TYPE_TP4, *//* TP_TYPE_TCP, or TP_TYPE_TPX. */int tsel_len;char tsel [MAX_TSEL_LEN];int nsap_len;char nsap [MAX_IP_ADDR_LEN]; /* If TP_TYPE_TP4, contains NSAP. */
/* If TP_TYPE_TCP, contains IP addr. */
/* Only used for “remote” addresses. */} PRES_ADDR;

注:根据现有的OSI协议,PSEL、SSEL和TSEL参数都被更改为最大4字节,这提高了MMS-EASE Lite的内存使用。该标准建议如下:

PSEL 4 - International Standard Profiles
SSEL 2 - GOSIP Ver2
TSEL 2 - GOSIP Ver2

传输类型TP_TYPE_TPX只能用于“本地”入口。这表示同时支持TP4和TCP。指针loc_dib_table和rem_dib_table的设置可以以任何适合目标平台的方式进行。以下示例代码模块提供了硬编码的示例(只有定义了HARD_CODED_CFG时才执行代码):

server.c
client.c

也可以使用osicfg.xml文件进行配置,详情可以参考以下内容。

3.5 使用XML输入文件进行协议栈配置

以下模块提供了使用Sisco通用配置实用程序来配置TP4 API, CLNP API以及DIB条目的示例:

osicfgx.c

这段代码处理以下配置文件:

osicfg.xml

配置文件osicfg.xml分为TP4、TCP、CLNP和DIB表项(网络地址)四个部分。由于篇幅所限,本文档不会详细描述该配置文件文件和Sisco通用配置实用程序的使用方法。

3.6 ACSE身份验证

以下内容描述了ISO/IEC 8650-1附录B中的ACSE认证相关内容。

acseauth.h文件包含了传递给用户和ASN.1解析器的身份验证结构体ACSE_AUTH_INFO。

如果不希望进行ACSE认证,发起调用的节点可以利用mvla_initiate_req服务向被调用节点发送一个初始化请求PDU。如果需要进行ACSE身份验证,ACSE用户必须调用mvla_initiate_req_ex,并传递一个指向ACSE_AUTH_INFO结构的指针,该结构包含他们希望发送给被调用节点的身份验证信息。身份验证信息的编码是按照ACSE规范进行的,在acse2enc.c中完成。

被调用侧将接收带有身份验证的请求PDU,并在acse2dec.c中对其进行解码。填写ACSE_AUTH_INFO结构,并通过u_mvl_connect_ind_ex传递给用户。用户既可以接受身份验证并返回成功,也可以拒绝身份验证并向发起调用的节点发送一个放弃验证的PDU。拒绝身份验证的原因被定义在acseauth.h的部分常量中,并且编码在放弃验证PDU中。

此外,一个指向响应身份验证结构体的指针将会发送给用户,该结构体在连接确认期间可能被发送回调用节点。在关联请求和关联响应APDUs中使用这种交换身份验证信息的方法可以提供双向身份验证。

如果调用方确实在AARE APDU中接收到身份验证,则该信息将在u_mvl_connect_cnf_ex中传递给用户。同样,这个函数可能返回成功或错误诊断,返回信息将会被编码中放弃验证PDU发送。

身份验证值本身在ACSE规范中定义。ACSE_AUTH_INFO结构可以使用密码机制(如ACSE规范中定义的那样)或其他机制。在“other”机制的情况下,用户需要处理认证值的ASN.1解码和编码。此外,cisco还可以提供基于证书的ACSE认证机制。

ACSE认证编码/解码被编译成MMS-EASE Lite库代码。关于ACSE认证示例代码,请参阅\mmslite\mvl\usr目录中提供的客户端、服务器或uca_srvr示例。

【翻译】第四章 MMS-EASE Lite底层相关推荐

  1. 《Undocumented Windows 2000 Secrets》翻译 --- 第四章(6)

    第四章  探索Windows 2000的内存管理机制 翻译:Kendiv( fcczj@263.net ) 更新:Sunday, February 17, 2005 声明:转载请注明出处,并保证文章的 ...

  2. Beginning WF 4.0翻译——第四章(传递参数)

    在第一章,我已经向你展示了在工作流中怎么使用variables(变量)和arguments(参数).跟编码类似,variables类似于类成员,而arguments类似于方法的参数.你已经在前三章使用 ...

  3. 《Fundamentals of Computer Grahpics》虎书第三版翻译——第四章 光线追踪

    光线追踪 计算机图形学的基本任务之一是绘制三维物体:获取一个场景或模型(由许多在3D空间中排列的几何物体组成),并生成一个二维图像(从一个特定的视角观察到的物体的图像).这和几个世纪以来建筑师和工程师 ...

  4. 转载:Beginning WF 4.0翻译——第四章(传递参数)

    在第一章,我已经向你展示了在工作流中怎么使用variables(变量)和arguments(参数).跟编码类似,variables类似于类成员,而arguments类似于方法的参数.你已经在前三章使用 ...

  5. Gradle 1.12用户指南翻译——第五十四章. 构建原生二进制文件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

  6. 我要翻译《Think Python》- 006 第四章 学习案例:接口设计

    本文翻自:Allen B. Downey --<Think Python> 原文链接:http://www.greenteapress.com/thinkpython/html/think ...

  7. 系统架构师学习笔记_第十四章_连载

    第十四章  基于ODP的架构师实践 14.1  基于ODP的架构开发过程 系统架构 反映了功能在系统系统构件中的 分布.基础设施相关技术.架构设计模式 等,它包含了架构的 原则 和 方法.构件关系 与 ...

  8. 深入理解Magento – 第四章 – 模型和ORM基础

    深入理解Magento 作者:Alan Storm 翻译:Hailong Zhang 第四章 – 模型和ORM基础 对于任何一个MVC架构,模型(Model)层的实现都是占据了很大一部分.对于Mage ...

  9. 【JVM】第四章 Java内存模型

    第四章 Java内存模型 文章目录 第四章 Java内存模型 一.物理机的并发问题 1.硬件的效率问题 2.缓存一致性问题 3.代码乱序执行优化问题 二.Java 内存模型 1.概念 2.Java 内 ...

  10. STM32固件库(标准外设库)入门学习 第四章OLED屏幕使用

    STM32固件库(标准外设库)入门学习 第四章OLED屏幕使用 本学习教程,参考B站江科大自化协STM32视频,型号为STM32F103C8T6. 文章目录 STM32固件库(标准外设库)入门学习 第 ...

最新文章

  1. 背包问题教程-01背包,完全背包,多重背包,混合背包 收藏
  2. 修改段落内容_英文论文修改技巧大全
  3. 【世界上最美丽的7张太阳照片】
  4. python模块time_Python模块:time模块详解(转)
  5. html代码范例_最佳HTML范例和HTML5范例
  6. sleep() wait() yield() join()
  7. java堆外内存为何比java堆更适合用来进行网络IO操作
  8. C++之MFC之Unicode转char*
  9. HITWH-PYTHON学习笔记(2)-20170706
  10. Debezium报错处理系列之三十四:The db history topic or its content is fully or partially missing. Please check d
  11. 核心乐理---音程名称
  12. Linux中使用宝塔面板部署tipask3.*超详细教程,吐血两天部署成功,把过程整理出来,送给被官方文档折磨的小白们~~~~
  13. springboot前后端分离 前端请求图片问题
  14. 百菜不如白菜 娃娃菜更营养吗
  15. 《搜索》— NYOJ 42—一笔画问题
  16. JQ input value取值再赋值
  17. 李航《统计学习方法》感知机代码
  18. js,提示,eclipse
  19. 【Django】开发日报_6_Day:手机号码管理系统-项目整合创建Bootstrap样式父类
  20. LAN8720A不能自动获取IP地址的问题

热门文章

  1. Google Chrome 应用商店上传扩展程序
  2. 想通过参加会议年入30万,没这些能力可不行——百格活动
  3. 哈工程自考计算机应用数学,自考本科计算机应用数学 01332
  4. AI 图片截取、ffmpeg使用及安装, anaconda环境,图片标注(labelme),模型训练(yolov5),CUDA+Pytorch安装及版本相关问题
  5. JAVA基本框架搭建(Maven,jetty,Jod…
  6. 酷壳陈皓:如何学好C语言
  7. 金仓数据库KingbaseES行列转换
  8. js中对象数组根据对象id分组并转map
  9. Lucas定理扩展Lucas
  10. Windows 安全系列05-U盘安全