PCSC那事儿(二十七--开始服务端代码分析)

 

 

服务端代码分析

 

服务端,明显比客户端复杂,而且还用到了多线程。

 

pcscdaemon.c 开始。从 main 开始。

 

继续继续 ...

190 int main(int argc, char **argv)

191 {

192         int rv;

193         char setToForeground;

194         char HotPlug;

195         char *newReaderConfig;

196         struct stat fStatBuf;

197         int opt;

198 #ifdef HAVE_GETOPT_LONG

199         int option_index = 0;

200         static struct option long_options[] = {

201                 {"config", 1, NULL, 'c'},

202                 {"foreground", 0, NULL, 'f'},

203                  {"help", 0, NULL, 'h'},

204                 {"version", 0, NULL, 'v'},

205                 {"apdu", 0, NULL, 'a'},

206                 {"debug", 0, NULL, 'd'},

207                 {"info", 0, NULL, 0},

208                 {"error", 0, NULL, 'e'},

209                 {"critical", 0, NULL, 'C'},

210                 {"hotplug", 0, NULL, 'H'},

211                 {"force-reader-polling", optional_argument, NULL, 0},

212                 {NULL, 0, NULL, 0}

213         };

214 #endif

 

 

 

200 行,看到 struct option long_options, 应该明白这些要做什么了。

就是解析命令行参数。

比如

输入命令: ./pcscd -f -d

程序要解析出 f d 选项,进行对应的处理。

215 #define OPT_STRING "c:fdhvaeCH"

216

217         rv = 0;

218         newReaderConfig = NULL;

219         setToForeground = FALSE;

220         HotPlug = FALSE;

221

222         /*

223          * test the version

224          */

225         if (strcmp(PCSCLITE_VERSION_NUMBER, VERSION) != 0)

226         {

227                 printf("BUILD ERROR: The release version number PCSCLITE_VERSION_NUMBER/n");

228                 printf("  in pcsclite.h (%s) does not match the release version number/n",

229                         PCSCLITE_VERSION_NUMBER);

230                 printf("  generated in config.h (%s) (see configure.in)./n", VERSION);

231

232                 return EXIT_FAILURE;

233         }

 

 

215 行,短选项,这里关系到一个 linux 下,不可移植的 api

那就是 getopt_long getopt .windows 中不存在这两个 api.

当然了,可以在 windows 下,自己重新实现这两个接口。

或者采用 boost 的可供移植的 program_options .  

 

225~233 行,进行版本比较。比较 config.h VERSION pcsclite.h

PCSCLITE_VERSION_NUMBER

 

PCSC/pcsclite.h

186 #define PCSCLITE_VERSION_NUMBER         "1.5.5" /**< Current version */

 

config.h

158 /* Version number of package */

159 #define VERSION "1.5.5"

 

 

当然是一致的了。

234

235         /*

236          * By default we create a daemon (not connected to any output)

237          * so log to syslog to have error messages.

238          */

239         DebugLogSetLogType(DEBUGLOG_SYSLOG_DEBUG);

240

 

 

 

234~240 行,系统日志相关。这个实现在一个单独的文件中。比较简单的。

现在的目标是,服务端。

 

241         /*

242           * Handle any command line arguments

243          */

244 #ifdef  HAVE_GETOPT_LONG

245         while ((opt = getopt_long (argc, argv, OPT_STRING, long_options, &option_index)) != -1) {

246 #else

247         while ((opt = getopt (argc, argv, OPT_STRING)) != -1) {

248 #endif

249                 switch (opt) {

250 #ifdef  HAVE_GETOPT_LONG

251                         case 0:

252                                 if (strcmp(long_options[option_index].name,

253                                         "force-reader-polling") == 0)

254                                         HPForceReaderPolling = optarg ? abs(atoi(optarg)) : 1;

255                                 break;

256 #endif

257                         case 'c':

258                                  Log2(PCSC_LOG_INFO, "using new config file: %s", optarg);

259                                 newReaderConfig = optarg;

260                                 break;

261

262                         case 'f':

263                                 setToForeground = TRUE;

264                                 /* debug to stderr instead of default syslog */

265                                 DebugLogSetLogType(DEBUGLOG_STDERR_DEBUG);

266                                 Log1(PCSC_LOG_INFO,

267                                          "pcscd set to foreground with debug send to stderr");

268                                 break;

269

270                         case 'd':

271                                 DebugLogSetLevel(PCSC_LOG_DEBUG);

272                                  break;

273

274                         case 'e':

275                                 DebugLogSetLevel(PCSC_LOG_ERROR);

276                                 break;

277

278                         case 'C':

279                                  DebugLogSetLevel(PCSC_LOG_CRITICAL);

280                                 break;

281

282                         case 'h':

283                                 print_usage (argv[0]);

284                                 return EXIT_SUCCESS;

285

286                         case 'v':

287                                 print_version ();

288                                 return EXIT_SUCCESS; 289

290                         case 'a':

291                                 (void)DebugLogSetCategory(DEBUG_CATEGORY_APDU);

292                                 break;

293

294                         case 'H':

295                                 /* debug to stderr instead of default syslog */

296                                 DebugLogSetLogType(DEBUGLOG_STDERR_DEBUG);

297                                 HotPlug = TRUE;

298                                 break;

299

300                         default:

301                                 print_usage (argv[0]);

302                                  return EXIT_FAILURE;

303                 }

304

305         }

306

307         if (argv[optind])

308         {

309                 printf("Unknown option: %s/n/n", argv[optind]);

310                 print_usage(argv[0]);

311                 return EXIT_SUCCESS;

312         }

 

245 行,

247 行开始参数解析了。

getopt_long getopt ,要理解吗?

或者已经理解了。那么看看 man 吧。 linux 里的男人。不知道女权主义者会怎么看待这个

man 命令。

 

打开终端,输入

#man getopt_long

出来帮助。够详细的,还有两个例子帮助说明。

 

 

说说这些选项的意义:

 

 

  -a, --apdu          把发送的 APDU 和接收的结果进入日志

  -c, --config          读卡器路径配置 reader.conf ,一般在 /etc/reader.conf

  -f, --foreground  直接运行,不要以 daemon 服务运行,把日志消息等都直接输入到终端    

  -h, --help            显示用法

  -H, --hotplug      强制重新扫描可用的读卡器

  -v, --version         显示程序的版本号

  -d, --debug          显示 low level 级别的调试信息

      --info             显示 info level 级别的调试信息 ( 默认的 level)

  -e  --error            显示 error level 级别的调试信息

  -C  --critical         仅仅显示 critical  level 级别的调试信息

  --force-reader-polling 查询方式检测设备的事件

 

满足下好奇心, reader.conf 的内容是?

# Configuration file for pcsc-lite

#

# This file has to be configured for serial and PCMCIA readers only.

# normal USB readers shall _not_ be configured here!( 这里是配置 serial PCMCIA 用的 )

#

# David Corcoran <corcoran@linuxnet.com>

 

#FRIENDLYNAME     "Generic Reader"

#DEVICENAME       /dev/ttySx_not_configured

#LIBPATH          /home/wjf/anotherday/pcsc/arm9/pcsc-lite-1.5.5/pcsc/drivers/libgen_ifd.so

#CHANNELID        0x0103F8

 

# End of file

这个文件是 serial PCMCIA 类型读卡器的配置文件, usb 类型读卡器的配置还得靠 /usr/local/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist 文件。

 

Info.plist 这个文件以后再说。

 

所以呢, serial PCMCIA 类型的读卡器在 /etc/reader.conf 配置。

usb 类型的读卡器在 /usr/local/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist 配置。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值