4.3. 高级 CI API¶
注意
此文档已过时。
本文档描述了符合 Linux DVB API 的高级 CI API。
采用高级 CI 方法,任何具有几乎任何随机架构的新卡都可以通过这种方式实现,switch 语句中的定义可以很容易地适应任何卡,从而无需任何额外的 ioctl。
缺点是驱动程序/硬件必须管理其余部分。对于应用程序程序员来说,只需按照 Linux DVB API 中定义的将数组发送/接收到/从 CI ioctl 即可。API 中没有进行任何更改来适应此功能。
4.3.1. 为什么需要另一个 CI 接口?¶
这是最常被问到的问题之一。嗯,这是一个好问题。严格来说,这不是一个新的接口。
CI 接口在 ca.h 中的 DVB API 中定义为
typedef struct ca_slot_info {
int num; /* slot number */
int type; /* CA interface this slot supports */
#define CA_CI 1 /* CI high level interface */
#define CA_CI_LINK 2 /* CI link layer level interface */
#define CA_CI_PHYS 4 /* CI physical layer level interface */
#define CA_DESCR 8 /* built-in descrambler */
#define CA_SC 128 /* simple smart card interface */
unsigned int flags;
#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
#define CA_CI_MODULE_READY 2
} ca_slot_info_t;
此 CI 接口遵循 CI 高级接口,而大多数应用程序并未实现该接口。因此,将重新审视该领域。
此 CI 接口的不同之处在于,它尝试容纳所有其他属于其他类别的基于 CI 的设备。
这意味着此 CI 接口仅在应用层处理 EN50221 样式标签,并且应用程序不负责会话管理。驱动程序/硬件将负责所有这些。
此接口纯粹是交换 APDU 的 EN50221 接口。这意味着在这种情况下,应用程序到驱动程序通信中不存在会话管理、链路层或传输层。就这么简单。驱动程序/硬件必须负责这些。
使用此高级 CI 接口,可以使用常规 ioctl 定义接口。
所有这些 ioctl 也对高级 CI 接口有效
#define CA_RESET _IO('o', 128) #define CA_GET_CAP _IOR('o', 129, ca_caps_t) #define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t) #define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t) #define CA_GET_MSG _IOR('o', 132, ca_msg_t) #define CA_SEND_MSG _IOW('o', 133, ca_msg_t) #define CA_SET_DESCR _IOW('o', 134, ca_descr_t)
在查询设备时,设备会产生如下信息
CA_GET_SLOT_INFO
----------------------------
Command = [info]
APP: Number=[1]
APP: Type=[1]
APP: flags=[1]
APP: CI High level interface
APP: CA/CI Module Present
CA_GET_CAP
----------------------------
Command = [caps]
APP: Slots=[1]
APP: Type=[1]
APP: Descrambler keys=[16]
APP: Type=[1]
CA_SEND_MSG
----------------------------
Descriptors(Program Level)=[ 09 06 06 04 05 50 ff f1]
Found CA descriptor @ program level
(20) ES type=[2] ES pid=[201] ES length =[0 (0x0)]
(25) ES type=[4] ES pid=[301] ES length =[0 (0x0)]
ca_message length is 25 (0x19) bytes
EN50221 CA MSG=[ 9f 80 32 19 03 01 2d d1 f0 08 01 09 06 06 04 05 50 ff f1 02 e0 c9 00 00 04 e1 2d 00 00]
并非所有来自 API 的 ioctl 都在驱动程序中实现,硬件的其他无法通过 API 实现的功能使用 CA_GET_MSG 和 CA_SEND_MSG ioctl 实现。使用 EN50221 样式包装器来交换数据,以保持与其他硬件的兼容性。
/* a message to/from a CI-CAM */
typedef struct ca_msg {
unsigned int index;
unsigned int type;
unsigned int length;
unsigned char msg[256];
} ca_msg_t;
数据流可以这样描述
App (User)
-----
parse
|
|
v
en50221 APDU (package)
--------------------------------------
| | | High Level CI driver
| | |
| v |
| en50221 APDU (unpackage) |
| | |
| | |
| v |
| sanity checks |
| | |
| | |
| v |
| do (H/W dep) |
--------------------------------------
| Hardware
|
v
高级 CI 接口使用 EN50221 DVB 标准,遵循标准可确保未来的兼容性。