PinPad

>w## Notice > * please include the header file "bwsdk_api.h" when you need to input pinblock `#include "bwsdk_api.h"` >i## data structure ``` /** * @brief Material of PINBLOCK */ typedef struct { unsigned char KeyArch; ///< Refer to Key_Arch_Type unsigned char KeyIdx; ///< key index unsigned char Mode; ///< Pin_Block_Mode_Type unsigned char PanLen; ///< Length of PAN unsigned char TradeInfoLen; ///< Length of Trade information unsigned char ListLen; ///< Length of PIN LEN list unsigned long TimeoutMs; ///< Timeout unsigned char Pan[20]; ///< PAN with check byte; Check byte should be set 0x00 if APP doesn't get it. unsigned char TradeInfo[8]; ///< Trade information unsigned char ExpPinLenList[12];///< Length of PIN permit. } Pin_Block_Material_Type; /** * @brief Event data of PINBLOCK * @see:: Pin_Block_Event */ typedef struct { unsigned char ucPinLen; ///< when event is PIN_EVENT_LEN, indicate the PIN length inputted unsigned char ucPinBlkLen; ///< when event is PIN_EVENT_PINBLOCK or PIN_EVENT_PINFREE, indicate the length of pinblock unsigned char ucKsnLen; ///< when event is PIN_EVENT_PINBLOCK or PIN_EVENT_PINFREE and using DUKPT, indicate the length of KSN int iErrCode; ///< when event is PIN_EVENT_ERR, indicate the error unsigned char aucPinBlock[32]; ///< when event is PIN_EVENT_PINBLOCK or PIN_EVENT_PINFREE, is PINBLOCK unsigned char aucKsn[10]; ///< when event is PIN_EVENT_PINBLOCK or PIN_EVENT_PINFREE and using DUKPT, is KSN } Pin_Block_Data; ``` >i## PedGetPinBlockRev ### Prototype `int PedGetPinBlockRev(Pin_Block_Material_Type *pstMaterial, PinBlockEventCB callback, Pin_Block_Data *pData);` ### Function * Get PinBlock ### Parameter |Name|Type|description| |-|-|-| |pstMaterial|Pin_Block_Material_Type *|PINBLOCK material| |callback|PinBlockEventCB|PIN event callback function| |pData|Pin_Block_Data *|PIN event data| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >s## Example ``` #define EMV_L2_DEFAULT_PIN_LIST_4 "\x00\x04\x06\x0C" #define EMV_L2_DEFAULT_PIN_LIST_5 "\x00\x06\x08\x0C\x0C" #define EMV_L2_DEFAULT_PIN_LIST_6 "\x00\x04\x06\x08\x0A\x0C" #define EMV_L2_DEFAULT_PIN_LIST_8 "\x00\x04\x05\x06\x07\x08\x0A\x0C" #define EMV_L2_DEFAULT_PIN_LIST_9 "\x00\x04\x05\x06\x07\x08\x09\x0A\x0C" #define EMV_L2_DEFAULT_PIN_LIST_10 "\x00\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C" /*Online pin callback*/ static int giPinEvent = PIN_EVENT_NONE; static int giPinErr = SUCCESS; static void Util_PinBlockEventCB(Pin_Block_Event event, Pin_Block_Data *data) { if (-1 == data->iErrCode) { giPinErr = ERR_TIMEOUT; } giPinEvent = event; } ///< online PIN input int Utils_InputOnlinePIN(unsigned int dispLine, unsigned int column, const char* panData, unsigned char *pinBlock, unsigned int *pinBlockSize, unsigned short timeout) { int iRet = ERR_CANCEL; char dispBuff[20]; unsigned char ucPinBlkLen; Pin_Block_Material_Type pPinMaterial = { 0 }; Pin_Block_Data pOnlinePin = { 0 }; if (!pinBlock || !pinBlockSize) { return ERR_PARAM; } ucPinBlkLen = *pinBlockSize; *pinBlockSize = 0; giPinErr = SUCCESS; giPinEvent = PIN_EVENT_NONE; pPinMaterial.KeyArch = KEY_ARCH_MKSK; pPinMaterial.KeyIdx = 0x06; pPinMaterial.Mode = PINBLOCK_MODE_ISO9564_FMT0; // Compute the pattern of pinblock pPinMaterial.TimeoutMs = timeout*1000; pPinMaterial.TradeInfoLen = 0x00; ///< exp pPinMaterial.ListLen = 10; if (pPinMaterial.ListLen > sizeof(pPinMaterial.ExpPinLenList)) { return ERR_PARAM; } memcpy(pPinMaterial.ExpPinLenList, EMV_L2_DEFAULT_PIN_LIST_10, pPinMaterial.ListLen); ///< pan if (panData) { pPinMaterial.PanLen = strlen(panData); if (pPinMaterial.PanLen > sizeof(pPinMaterial.Pan)) { return ERR_PARAM; } memcpy(pPinMaterial.Pan, panData, pPinMaterial.PanLen); } memset(dispBuff, '*', sizeof(dispBuff)); if (PedGetPinBlockRev(&pPinMaterial, Util_PinBlockEventCB, &pOnlinePin) != 0){ // PIN input times exceed the limit, error code is -307, corresponding hexadecimal: FECD KbFlush(); return ERR_DRV; } while (1) { if (!GetSysStatus()) { PedInputCancelRev(); iRet = ERR_CANCEL; break; } switch (giPinEvent) { case PIN_EVENT_NONE: ///< No input Sleep(50); continue; case PIN_EVENT_LEN: ///< Have input giPinEvent = PIN_EVENT_NONE; mmi_clearLine(dispLine); mmi_display((DISP_VAlign)dispLine, column, "%*.*s", 0, pOnlinePin.ucPinLen, dispBuff); continue; case PIN_EVENT_COMPLETE:///< Input to complete iRet = SUCCESS; break; case PIN_EVENT_PINFREE: ///< Press ok iRet = SUCCESS; break; case PIN_EVENT_INVALID: giPinEvent = PIN_EVENT_NONE; continue; case PIN_EVENT_EXIT: ///< cancel iRet = ERR_CANCEL; break; case PIN_EVENT_ERR: iRet = ERR_END; if (giPinErr != SUCCESS) { iRet = giPinErr; } break; default: iRet = ERR_TIMEOUT; break; } break; } if (SUCCESS == iRet) { if (pOnlinePin.ucPinBlkLen > ucPinBlkLen) { return ERR_PARAM; } if (PIN_EVENT_PINFREE != giPinEvent) { *pinBlockSize = pOnlinePin.ucPinBlkLen; memcpy(pinBlock, pOnlinePin.aucPinBlock, pOnlinePin.ucPinBlkLen); } } else { pOnlinePin.ucPinBlkLen = 0; memset(pOnlinePin.aucPinBlock, 0, sizeof(pOnlinePin.aucPinBlock)); } KbFlush(); return iRet; } ///< On line PIN input int InputOnlinePINDemo(void) { int iRet = SUCCESS; unsigned int iLen; unsigned int dispLine = DISP_Line1; unsigned char PINData[16]; char *panData = "1234567890123456"; mmi_clearLine(DISP_ClearALL); mmi_display((DISP_VAlign)(dispLine++), 0, "Input online password"); mmi_display((DISP_VAlign)(dispLine++), 0, "Input your password"); mmi_display((DISP_VAlign)(dispLine--), 0, "No password press[O]"); /*!< --------------------------------------------------------------------*/ memset(PINData, 0, sizeof(PINData)); iLen = sizeof(PINData); iRet = Utils_InputOnlinePIN((DISP_VAlign)(dispLine), 0, panData, PINData, &iLen, 60); return iRet; } ```