Browse Source

#IQRV #comment [DeviceControl] 硬件模块测试打通

gifur 4 years ago
parent
commit
06e51aa51f

+ 301 - 0
DevAdapter/include/CardIssuerClassPrivate.h

@@ -0,0 +1,301 @@
+/////////////////////////////////////////////////////////////////////////////////
+///	Copyright (c) 2012 China Merchants Bank, all rights reserved	       	  ///
+///	  Adapter Interface for Card Issuer.                          	       	  ///
+///	                                                             	       	  ///
+///	                                                             	       	  ///
+/////////////////////////////////////////////////////////////////////////////////
+#ifndef __CARD_ISSUER_CLASS_H
+#define __CARD_ISSUER_CLASS_H
+#pragma once
+#include "DeviceBaseClass.h"
+#include "CardMix.h"
+
+//卡库平面、凹、凸(金,银)色带的状态
+enum KakuPrintStatusEnum
+{
+	//平面印刷色带的状态
+	CI_KAKU_PLAIN_COLOR_TAPE_FULL,	//
+	CI_KAKU_PLAIN_COLOR_TAPE_LOW,	//
+	CI_KAKU_PLAIN_COLOR_TAPE_EMPTY,	//
+	//凹字印刷色带的状态
+	CI_KAKU_CONCAVE_COLOR_TAPE_FULL,	//
+	CI_KAKU_CONCAVE_COLOR_TAPE_LOW,	//
+	CI_KAKU_CONCAVE_COLOR_TAPE_EMPTY,	//
+	//凸字色带的状态(金色)
+	CI_KAKU_CONVEX_COLOR_TAPE_GOLD_FULL,	//
+	CI_KAKU_CONVEX_COLOR_TAPE_GOLD_LOW,	//
+	CI_KAKU_CONVEX_COLOR_TAPE_GOLD_EMPTY,	//
+	//凸字色带的状态(银色)
+	CI_KAKU_CONVEX_COLOR_TAPE_SILVER_FULL,	//
+	CI_KAKU_CONVEX_COLOR_TAPE_SILVER_LOW,	//
+	CI_KAKU_CONVEX_COLOR_TAPE_SILVER_EMPTY,	//
+};
+struct CardIssuerStatus 
+{ 
+	CardStatusEnum eMedia;	//state about card
+	RtBinStatusEnum eRetainBin;
+	DWORD dwRetainCount;	//回收箱容量
+	//根据实际的卡箱数量对相关字段进行赋值
+	IssHopperStatusEnum eIssuerBin[12];//0,1,2,... => hopper 1,2,3,... 需要对1,2,3,...三个卡箱进行对应赋值
+	DWORD dwIssuerCount[12];	//发卡箱容量,0,1,2,... => 1,2,3,...
+	KakuPrintStatusEnum eKakuTape[8];//eKakuTape[0],eKakuTape[1],eKakuTape[2],eKakuTape[3]分别存放平面,凹,凸(金),凸(银)的状态
+};
+struct SAMStatus
+{
+	int isActive;//0:Inactive; 1:acitve
+	int chosenOfSAM;//the selected sam number:1,2,...
+};
+
+/** 该文件存在的意义是因为下面这个字段的定义与密码键盘头文件定义有冲突且值不一样
+为了保证密码键盘和发卡器的头文件能同时在一个编译单元中引用,所以特意拷贝了一份并修改了该参数的命名
+[Gifur@20211019]*/
+const int MAX_WORKING_KEY_SIZE_PRIVATE = 64;
+const int MAX_CHECK_CODE_SIZE = 16;
+const int MAX_TEMP_DATA_SIZE = 64;
+const int MAX_KAKU_FILE_SIZE = 256;
+const int MAX_KAKU_FIELDS_SIZE = 1024;
+
+//SCI:SplitCardIssuer
+struct SCIKeyInfo
+{
+	BYTE key[MAX_WORKING_KEY_SIZE_PRIVATE];
+	DWORD dwSize;
+};
+struct SCICheckCode
+{
+	BYTE code[MAX_CHECK_CODE_SIZE];
+	DWORD dwSize;
+};
+struct SCITempData
+{
+	BYTE data[MAX_TEMP_DATA_SIZE];
+	DWORD dwSize;
+};
+enum SCIParamType
+{
+	ParamBeep,
+	ParamLed,
+	ParamLevelTime,
+};
+enum SCILightType
+{
+	SCILight_EjectCard,
+	SCILight_CMBLogo,
+};
+enum SCIBluetoothCMD
+{
+	SCIBluetooth_Open,	//打开蓝牙
+	SCIBluetooth_Close,	//关闭蓝牙
+	SCIBluetooth_Hide,	//隐藏蓝牙信号
+	SCIBluetooth_Show,	//显示蓝牙信号
+};
+struct KakuPrintInfo
+{
+	char formPath[MAX_KAKU_FILE_SIZE];	//存储form文件绝对路径
+	char fields[MAX_KAKU_FIELDS_SIZE];	//存储打印内容参数
+};
+
+class CardIssuerClass : public DeviceBaseClass
+{
+public:
+	//
+	//	本接口几乎废弃不用。连接卡机,请使用DevOpenEx替代本接口
+	//	Connect to device and do initialization.
+	//	In case of power off or initialization,if the card is held in CardIssuer,move card
+	//	to Mag read/write position or doing nothing.
+	//	Retract counter will work.
+	//	Make preparations for controlling the device.
+	//	Arguments:
+	//	- dwPort[in]		com port number
+	//	- dwBaudRate[in]	Baud rate
+	//
+	virtual ErrorCodeEnum DevOpen(DWORD dwPort,DWORD dwBaudRate) = 0;
+	//
+	//	Get card issuer status
+	//
+	virtual ErrorCodeEnum GetDevStatus(CardIssuerStatus &devStatus) = 0;
+	//
+	//	Get device serial number.
+	//	设备唯一标识,且需贴在设备外壳上
+	virtual ErrorCodeEnum GetDeviceSN(char *&pDevSN) = 0;
+	//
+	//	Move card to specified position.
+	//	hopperNo:多卡箱发卡时指定发卡箱号(面对发卡机,从左往右依次是1,2,3,...号卡箱)
+	//		卡库:卡片从卡库加卡箱移动到读卡器,eCardPos为CI_MOVECARD_FROM_HOPPER,hopperNo固定传入99
+	//
+	virtual ErrorCodeEnum MoveCard(CardPosEnum eCardPos, int hopperNo = 1) = 0;
+	//
+	//	Set card entry
+	//
+	virtual ErrorCodeEnum SetCardInType(CardInEnum eCardIn) = 0;
+
+	//
+	//	Read data from magnetic track.
+	//
+	virtual ErrorCodeEnum MagRead(MagTracks &magTracks) = 0;
+	//
+	//	Write data to magnetic track.
+	//
+	virtual ErrorCodeEnum MagWrite(MagTracks magTracks,MagWriteModeEnum eWriteMode) = 0;
+	//
+	//	Set retract counter
+	//
+	virtual ErrorCodeEnum SetRetractCounter(DWORD dwCount) = 0;
+	//
+	//	Set issuer counter
+	//	hopperNo:多卡箱发卡时指定发卡箱号(面对发卡机,从左往右依次是1,2,3,...号卡箱)
+	//
+	virtual ErrorCodeEnum SetIssuerCounter(DWORD dwCount,int hopperNo=1) = 0;
+	//
+	//	Active contact IC card
+	//
+	virtual ErrorCodeEnum ActiveICCard() = 0;
+	//
+	//	Move IC card to contact position
+	//
+	virtual ErrorCodeEnum ContactIC() = 0;
+	//
+	//	Release IC contact
+	//
+	virtual ErrorCodeEnum ReleaseIC() = 0;
+	//
+	//	Warm reset card(IC)
+	//
+	virtual ErrorCodeEnum WarmReset() = 0;
+	//
+	//	APDU:Application Protocol Data Unit
+	//	CmdSend.lpCmd:Command-APDU
+	//	CmdRecv.lpData:Response-APDU
+	//
+	virtual ErrorCodeEnum ICCommand(CmdInfo sendBuf,CmdInfo &recvBuf) = 0;
+	//////////////////SAM 卡操作部分////////////////////
+	virtual ErrorCodeEnum SAMActive(BYTE vcc=0x30){ return Error_NotImpl; };
+	virtual ErrorCodeEnum SAMDeactivate(){ return Error_NotImpl; };
+	virtual ErrorCodeEnum SAMWarmReset(){ return Error_NotImpl; };
+	virtual ErrorCodeEnum SAMQueryStatus(SAMStatus &samStatus){ return Error_NotImpl; };
+	virtual ErrorCodeEnum SAMSelect(const int sn){ return Error_NotImpl; };
+	//即时制卡卡库需要实现SAMCommand,用来执行apdu指令
+	virtual ErrorCodeEnum SAMCommand(CmdInfo sendBuf, CmdInfo &recvBuf){ return Error_NotImpl; };
+	//即时制卡卡库需要实现ActiveICCardATR,用来激活卡片,返回ATR
+	virtual ErrorCodeEnum ActiveICCardATR(CmdInfo &atrBuf){return Error_NotImpl;}
+	
+	////////////////卡面打印部分(非即时制卡的卡面印刷,即时制卡的卡面打印接口为PrintCardFaceRightNow),部分机型(例如合肥分行大机)有此功能//////////////////
+	virtual ErrorCodeEnum Print(BYTE *&data, const int dataSize,const int side){ return Error_NotImpl; };
+	virtual ErrorCodeEnum QueryPrinterStatus(){ return Error_NotImpl;};
+	
+	////////////////////////////////////////////////////////////////////////////
+	////////非接(IC)部分 start,没有此部分,在接口实现中直接返回Error_NotImpl///////////////
+	////////////////////////////////////////////////////////////////////////////
+	//	Active contactless IC card(Type A,B,Mifare)
+	//	The first,second,third activation order decided by fstType,scdType,thdType respectively
+	//	fstType,scdType,thdType can be one of 'A','B','M','0'(30H,no type)
+	//	outType indicates the type of  activation result
+	//
+	virtual ErrorCodeEnum ActiveContactlessICCard(char fstType, char scdType, char thdType, char &outType) = 0;
+	//
+	//	Deactivate contact IC card
+	//
+	virtual ErrorCodeEnum DeactivateICCard() = 0;
+	//
+	//	Deactivate contactless IC card
+	//
+	virtual ErrorCodeEnum DeactContactlessICCard() = 0;
+	//
+	//	RF Mifare Classic protocol operation
+	//	Arguments:
+	//	- eFunType:function type as load key,authentication and so on
+	//	- sendBuf:[parameter][data]
+	//	- recvBuf:[status(1byte)][return data]
+	//
+	virtual ErrorCodeEnum MifareCommand(MifareFuctionEnum eFunType, CmdInfo sendBuf, CmdInfo &recvBuf) = 0;
+	//
+	//	RF Type A,B command.
+	//	APDU:Application Protocol Data Unit
+	//	Arguments:
+	// 	- CmdSend.lpCmd:Command-APDU
+	// 	- CmdRecv.lpData:Response-APDU
+	//
+	virtual ErrorCodeEnum RFTypeABCommand(CmdInfo sendBuf, CmdInfo &recvBuf) = 0;
+	////////非接(IC)部分 end/////////////////////////////////////////////////////////
+
+	//	发卡机调用打开设备
+	//	1. btOpenType:设定通过哪种方式连接设备,由DevOpenType的枚举值组合。usb及蓝牙设备连接可忽略dwPort,dwBaudRate
+	//	2.通过pDevSN来指定连接对应设备号的蓝牙发卡机(考虑存在多台发卡机的情况)
+	//		例如通过蓝牙或者usb连接设备,则btOpenType = (DEV_OPEN_TYPE_USB|DEV_OPEN_TYPE_BLUETOOTH)
+	//	3. btType返回设备实际通过哪种方式相连,返回值参考DevOpenType(大机,卡库参考下一条)
+	//	4.对于大机(柜式可视柜台,卡库)dwPort,dwBaudRate传入端口,波特率,btOpenType为DEV_OPEN_TYPE_COM,pDevSN为""
+	//		,btType返回值表示卡槽数量(例如目前存在单卡槽1,双卡槽2,三卡槽3的机型)
+	//	
+	virtual ErrorCodeEnum DevOpenEx(DWORD dwPort, DWORD dwBaudRate, BYTE btOpenType,const char *pDevSN, BYTE &btType) = 0;
+
+	/////////////////////////////////////////////////////////////////////////
+	///以下是便携式卡机特有API,接口实现中其他机型直接返回Error_NotImpl即可//
+	/////////////////////////////////////////////////////////////////////////
+
+	//	返回值Error_Succeed表示成功,其他值表示失败
+	//	iStatus   0:成功   -1:银行公钥不存在   -2:产生设备密钥故障  -x:其他厂商自定义故障
+	//	Cr1:随机数r1的密文; Cr3:随机数r3的密文,dKey:用银行公钥加密的设备公钥密文
+	//	r1,r3第16字节为数据完整性校验字节,例如r1为B1B2...B15B16,则B16=B1^B2^...^B15
+	virtual ErrorCodeEnum TransferEnInit(int &iStatus, BYTE *&Cr1, int &lenR1, BYTE *&Cr3, int &lenR3, BYTE *&dKey, int &lenKey) = 0;
+
+	//	返回值Error_Succeed表示成功,其他值表示失败
+	//	iStatus   0:成功   -x:厂商自定义故障
+	//	r2第16字节为数据完整性校验字节,例如r2为B1B2...B15B16,则B16=B1^B2^...^B15
+	virtual ErrorCodeEnum SetR2(int &iStatus, BYTE *pCr2, int lenR2) = 0;
+	//
+	//	设置会话密钥
+	//	pWorkingKey:会话密钥,传递16进制的字符形式,例如0x123456FFAB  --> "123456FFAB"
+	virtual ErrorCodeEnum SendWorkingKey(const char *pWorkingKey) = 0;
+
+	//安全锁接口部分 begin
+	virtual ErrorCodeEnum SLLoadKey(const SCIKeyInfo key) = 0;
+	//case ParamBeep: value:0,close beep;value:1,open beep
+	//case ParamLed: value:0,close led;value:1,open led
+	//case ParamLevelTime: value:the duration of level,100ms per unit
+	//		ex.	the value 10 means duration time is 1 second
+	virtual ErrorCodeEnum SLSetParam(SCIParamType eType, int value) = 0;
+	virtual ErrorCodeEnum SLLock() = 0;
+	virtual ErrorCodeEnum SLUnLock(const SCICheckCode checkCode, bool bTemp = true) = 0;
+	virtual ErrorCodeEnum SLGetTempData(SCITempData &ksnData, SCITempData &ramData) = 0;
+	virtual ErrorCodeEnum SLOpenDoor(const SCITempData data) = 0;
+	//安全锁接口部分 end
+
+	//蓝牙控制部分 start
+	//蓝牙指令控制,命令参看SCIBluetoothCMD说明
+	virtual ErrorCodeEnum BluetoothControl(SCIBluetoothCMD eCmd) = 0;
+	//修改配对密码
+	virtual ErrorCodeEnum BluetoothModifyKey(unsigned char *key) = 0;
+	//修改蓝牙设备名称
+	virtual ErrorCodeEnum BluetoothModifyName(unsigned char *name) = 0;
+	//获取版本信息
+	virtual ErrorCodeEnum BluetoothGetVersion(char *&version) = 0;
+	//获取连接设备名称
+	virtual ErrorCodeEnum BluetoothGetConnectName(unsigned char *&name) = 0;
+	//获取连接设备信号强度
+	virtual ErrorCodeEnum BluetoothGetSignalStrength(unsigned char *&signal) = 0;
+	//蓝牙控制部分 end
+	
+	//控制灯光
+	//eLight:所控制的灯 ;
+	//bOnOff:true 亮灯;fasle 灭灯
+	virtual ErrorCodeEnum LightControl(SCILightType eLight, bool bOnOff) = 0;
+	//以百分比数值返回剩余电量(1-100),例如剩余51%,则bat赋值为51
+	virtual ErrorCodeEnum QueryBatteryPower(int &bat) = 0;
+	//oiltest
+	//virtual ErrorCodeEnum EncryptData(TempData ramData, TempData bdk, TempData curksn, TempData &encryptedData) = 0;
+	//把卡片从读卡器移动到指定卡槽位
+	virtual ErrorCodeEnum MoveCardToSlot(int slot){return Error_NotImpl;}
+	//把卡片从指定卡槽位移动到读卡器
+	virtual ErrorCodeEnum MoveCardFromSlot(int slot){return Error_NotImpl;}
+	//读取卡号
+	//优先从IC卡解析卡号,如果纯磁条卡,则返回磁道解析的卡号
+	virtual ErrorCodeEnum ReadAccount(CardNo &cardNo){return Error_NotImpl;}
+	//获取总卡槽数
+	virtual ErrorCodeEnum GetSlotSum(int &sum){return Error_NotImpl;}
+	//获取卡槽状态
+	virtual ErrorCodeEnum QuerySlotsStatus(SlotStatus &slots,const int slot,bool bFull=false){return Error_NotImpl;}
+	//即时制卡卡库专用接口
+	virtual ErrorCodeEnum PrintCardFaceRightNow(const KakuPrintInfo printInfo){return Error_NotImpl;}
+};
+
+#endif //__CARD_ISSUER_CLASS_H

+ 162 - 1
Module/mod_DeviceControl/DeviceAdapterCheckerImpl.cpp

@@ -2,7 +2,14 @@
 
 
 #include "PinPadClass.h"
-
+#include "CardIssuerClassPrivate.h"
+#include "IDCerClass.h"
+#include "RFICClass.h"
+#include "HSPScannerClass.h"
+#include "FingerPrintClass.h"
+#include "WatchDogClass.h"
+#include "GpioClass.h"
+#include "UpsClass.h"
 
 ErrorCodeEnum CAdapterLoadChecker::CheckDeviceAndAdapterAvailable(
     const VendorLibInfoEx& libInfo, DWORD& dwErrorCode, CSimpleStringA& strErrMsg)
@@ -39,20 +46,174 @@ ErrorCodeEnum CAdapterLoadChecker::CheckDeviceAndAdapterAvailable(
     }
     break;
     case 1: //CardIssuer
+    {
+        DevAdptLibHelper<CardIssuerClass> devImpl;
+        result = devImpl.LoadUp(libInfo.strDepDirWithSlash + libInfo.toLibNameString());
+        Dbg("Load returned: %s", SpStrError(result));
+        if (Error_Succeed == result) {
+            Dbg("%s: to open %p, %d, %d", __FUNCTION__, devImpl.GetDevPointer(), libInfo.dwPort, libInfo.dwBaudRate);
+            BYTE noUse;
+            result = devImpl->DevOpenEx(libInfo.dwPort, libInfo.dwBaudRate, DEV_OPEN_TYPE_COM, "", noUse);
+            Dbg("open result: %s", SpStrError(result));
+            if (result != Error_Succeed) {
+                DevErrorInfo devErrInfo;
+                memset(&devErrInfo, 0, sizeof(DevErrorInfo));
+                devImpl->GetLastErr(devErrInfo);
+                strErrMsg = CSimpleStringA::Format("打开设备失败:[%s] %s", SpStrError(result), devErrInfo.szErrMsg);
+            }
+        } else {
+            strErrMsg = CSimpleStringA::Format("文件加载或获取对象失败:%s", SpStrError(result));
+        }
+        devImpl.TearDown();
+    }
         break;
     case 2: //IDCertificate
+    {
+        DevAdptLibHelper<IDCerClass> devImpl;
+        result = devImpl.LoadUp(libInfo.strDepDirWithSlash + libInfo.toLibNameString());
+        Dbg("Load returned: %s", SpStrError(result));
+        if (Error_Succeed == result) {
+            Dbg("%s: to open %p, %d", __FUNCTION__, devImpl.GetDevPointer(), libInfo.dwPort);
+            result = devImpl->DevOpen(libInfo.dwPort);
+            Dbg("open result: %s", SpStrError(result));
+            if (result != Error_Succeed) {
+                DevErrorInfo devErrInfo;
+                memset(&devErrInfo, 0, sizeof(DevErrorInfo));
+                devImpl->GetLastErr(devErrInfo);
+                strErrMsg = CSimpleStringA::Format("打开设备失败:[%s] %s", SpStrError(result), devErrInfo.szErrMsg);
+            }
+        } else {
+            strErrMsg = CSimpleStringA::Format("文件加载或获取对象失败:%s", SpStrError(result));
+        }
+        devImpl.TearDown();
+    }
         break;
     case 3: //ContactlessCard
+    {
+        DevAdptLibHelper<RFICClass> devImpl;
+        result = devImpl.LoadUp(libInfo.strDepDirWithSlash + libInfo.toLibNameString());
+        Dbg("Load returned: %s", SpStrError(result));
+        if (Error_Succeed == result) {
+            Dbg("%s: to open %p, %d, %d", __FUNCTION__, devImpl.GetDevPointer(), libInfo.dwPort, libInfo.dwBaudRate);
+            result = devImpl->DevOpen(libInfo.dwPort, libInfo.dwBaudRate);
+            Dbg("open result: %s", SpStrError(result));
+            if (result != Error_Succeed) {
+                DevErrorInfo devErrInfo;
+                memset(&devErrInfo, 0, sizeof(DevErrorInfo));
+                devImpl->GetLastErr(devErrInfo);
+                strErrMsg = CSimpleStringA::Format("打开设备失败:[%s] %s", SpStrError(result), devErrInfo.szErrMsg);
+            }
+        } else {
+            strErrMsg = CSimpleStringA::Format("文件加载或获取对象失败:%s", SpStrError(result));
+        }
+        devImpl.TearDown();
+    }
         break;
     case 4: //HSPScanner
+    {
+        DevAdptLibHelper<CHSPSClass> devImpl;
+        result = devImpl.LoadUp(libInfo.strDepDirWithSlash + libInfo.toLibNameString());
+        Dbg("Load returned: %s", SpStrError(result));
+        if (Error_Succeed == result) {
+            Dbg("%s: to open %p", __FUNCTION__, devImpl.GetDevPointer());
+            result = devImpl->DevOpen();
+            Dbg("open result: %s", SpStrError(result));
+            if (result != Error_Succeed) {
+                DevErrorInfo devErrInfo;
+                memset(&devErrInfo, 0, sizeof(DevErrorInfo));
+                devImpl->GetLastErr(devErrInfo);
+                strErrMsg = CSimpleStringA::Format("打开设备失败:[%s] %s", SpStrError(result), devErrInfo.szErrMsg);
+            }
+        } else {
+            strErrMsg = CSimpleStringA::Format("文件加载或获取对象失败:%s", SpStrError(result));
+        }
+        devImpl.TearDown();
+    }
         break;
     case 5: //FingerPrint
+    {
+        DevAdptLibHelper<FingerPrintClass> devImpl;
+        result = devImpl.LoadUp(libInfo.strDepDirWithSlash + libInfo.toLibNameString());
+        Dbg("Load returned: %s", SpStrError(result));
+        if (Error_Succeed == result) {
+            Dbg("%s: to open %p, %d, %d", __FUNCTION__, devImpl.GetDevPointer(), libInfo.dwPort, libInfo.dwBaudRate);
+            result = devImpl->DevOpen(libInfo.dwPort, libInfo.dwBaudRate);
+            Dbg("open result: %s", SpStrError(result));
+            if (result != Error_Succeed) {
+                DevErrorInfo devErrInfo;
+                memset(&devErrInfo, 0, sizeof(DevErrorInfo));
+                devImpl->GetLastErr(devErrInfo);
+                strErrMsg = CSimpleStringA::Format("打开设备失败:[%s] %s", SpStrError(result), devErrInfo.szErrMsg);
+            }
+        } else {
+            strErrMsg = CSimpleStringA::Format("文件加载或获取对象失败:%s", SpStrError(result));
+        }
+        devImpl.TearDown();
+    }
         break;
     case 6: //WatchDog
+    {
+        DevAdptLibHelper<WatchDogClass> devImpl;
+        result = devImpl.LoadUp(libInfo.strDepDirWithSlash + libInfo.toLibNameString());
+        Dbg("Load returned: %s", SpStrError(result));
+        if (Error_Succeed == result) {
+            Dbg("%s: to open %p", __FUNCTION__, devImpl.GetDevPointer());
+            result = devImpl->DevOpen();
+            Dbg("open result: %s", SpStrError(result));
+            if (result != Error_Succeed) {
+                DevErrorInfo devErrInfo;
+                memset(&devErrInfo, 0, sizeof(DevErrorInfo));
+                devImpl->GetLastErr(devErrInfo);
+                strErrMsg = CSimpleStringA::Format("打开设备失败:[%s] %s", SpStrError(result), devErrInfo.szErrMsg);
+            }
+        } else {
+            strErrMsg = CSimpleStringA::Format("文件加载或获取对象失败:%s", SpStrError(result));
+        }
+        devImpl.TearDown();
+    }
         break;
     case 7: //Gpio
+    {
+        DevAdptLibHelper<GpioClass> devImpl;
+        result = devImpl.LoadUp(libInfo.strDepDirWithSlash + libInfo.toLibNameString());
+        Dbg("Load returned: %s", SpStrError(result));
+        if (Error_Succeed == result) {
+            GpioInitParam param = { libInfo.dwPort, libInfo.dwBaudRate, 4, {true, true, false, true} };
+            Dbg("%s: to open %p, %d, %d", __FUNCTION__, devImpl.GetDevPointer(), libInfo.dwPort, libInfo.dwBaudRate);
+            result = devImpl->DevOpen(param);
+            Dbg("open result: %s", SpStrError(result));
+            if (result != Error_Succeed) {
+                DevErrorInfo devErrInfo;
+                memset(&devErrInfo, 0, sizeof(DevErrorInfo));
+                devImpl->GetLastErr(devErrInfo);
+                strErrMsg = CSimpleStringA::Format("打开设备失败:[%s] %s", SpStrError(result), devErrInfo.szErrMsg);
+            }
+        } else {
+            strErrMsg = CSimpleStringA::Format("文件加载或获取对象失败:%s", SpStrError(result));
+        }
+        devImpl.TearDown();
+    }
         break;
     case 8: //Ups
+    {
+        DevAdptLibHelper<UpsClass> devImpl;
+        result = devImpl.LoadUp(libInfo.strDepDirWithSlash + libInfo.toLibNameString());
+        Dbg("Load returned: %s", SpStrError(result));
+        if (Error_Succeed == result) {
+            Dbg("%s: to open %p, %d, %d", __FUNCTION__, devImpl.GetDevPointer(), libInfo.dwPort, libInfo.dwBaudRate);
+            result = devImpl->DevOpen(libInfo.dwPort, libInfo.dwBaudRate);
+            Dbg("open result: %s", SpStrError(result));
+            if (result != Error_Succeed) {
+                DevErrorInfo devErrInfo;
+                memset(&devErrInfo, 0, sizeof(DevErrorInfo));
+                devImpl->GetLastErr(devErrInfo);
+                strErrMsg = CSimpleStringA::Format("打开设备失败:[%s] %s", SpStrError(result), devErrInfo.szErrMsg);
+            }
+        } else {
+            strErrMsg = CSimpleStringA::Format("文件加载或获取对象失败:%s", SpStrError(result));
+        }
+        devImpl.TearDown();
+    }
         break;
     default:
         result = Error_NotSupport;