Manage Card Information

A card is a basic unit, which can link with multiple face pictures and fingerprints, for access control in this manual. So, before starting any other operations, you should add cards and apply the card information (e.g., card number, card type, group, permissions, and so on) to access control devices.

  • Make sure you have called NET_DVR_Init to initialize the development resources.

  • Make sure you have called NET_DVR_Login_V40 to log in to device.

Figure 1 Programming Flow of Managing Card Information

  1. Call NET_DVR_GetDeviceAbility, specify the capability type (dwAbilityType) to "ACS_ABILITY" (macro definition value: 0x801), and set the condition buffer (pCondBuffer) to the message XML_Desc_AcsAbility for getting access control capability to check if managing card information is supported by device.

    The access control capability is returned in the message XML_AcsAbility by the output buffer (pOutBuffer).

    If the node <Card> is returned in the message, it indicates that managing card information is supported by device, and you can perform the following steps.

    Otherwise, managing card information is not supported, please end this task.

  2. Perform the following operation(s) to get or apply card information.
    Note:

    Before applying card information, you can configure the access permission schedule template, refer to Configure Access Permission Control Schedule for details, and link the template to the card. Otherwise, the default template will be linked.

    Option Description

    Get Card Information

    1. Call NET_DVR_StartRemoteConfig with NET_DVR_GET_CARD_CFG_V50 (command No.: 2178) and set the input buffer (lpInBuffer) to NET_DVR_CARD_CFG_COND for setting up persistent connection and setting callback function (fRemoteConfigCallback).

      Note:

      The card information is returned in the structure NET_DVR_CARD_CFG_V50 by the output buffer (lpBuffer) of callback function.

    2. Call NET_DVR_SendRemoteConfig, specify data type (dwDataType) to "ENUM_ACS_SEND_DATA", and set sending buffer (pSendBuf) to NET_DVR_CARD_CFG_SEND_DATA for getting a specific card information.

    Apply Card Information

    1. Call NET_DVR_StartRemoteConfig with NET_DVR_SET_CARD_CFG_V50 (command No.: 2179) and set input buffer (lpInBuffer) to NET_DVR_CARD_CFG_COND for setting up persistent connection and setting callback function (fRemoteConfigCallback).

    2. Call NET_DVR_SendRemoteConfig, specify data type (dwDataType) to "ENUM_ACS_SEND_DATA", and set sending buffer (pSendBuf) to NET_DVR_CARD_CFG_V50 for applying the card information.

      Note:

      The applying status is returned by the output buffer (lpBuffer) of callback function.

  3. Call NET_DVR_StopRemoteConfig to disconnect the persistent connection.

Sample Code for Getting and Applying Card Information

#include <stdio.h>
#include <iostream>
#include <afx.h>
#include "Windows.h"
#include "HCNetSDK.h"
using namespace std;

LONG m_lSetCardCfgHandle;
LONG m_lGetCardCfgHandle;
CString m_csCardNo;
CString m_csCardPassword;
BOOL bGetCardCfgFinish = FALSE;
BOOL bSetCardCfgFinish = FALSE;

void CALLBACK g_fGetGatewayCardCallback(DWORD dwType, void* lpBuffer, DWORD dwBufLen, void* pUserData)
{
	//As the operations with long time comsumption are not allowed in the callback function,
        //do not call the API of HCNetSDK.DLL in the callback function.
	//The following code is for reference only, actually, processing data in the callback function is not suggested.
	//for example, process in the message response function as PostMessage

	if (dwType == NET_SDK_CALLBACK_TYPE_DATA)//Data information
	{
		LPNET_DVR_CARD_CFG_V50 lpCardCfg = new NET_DVR_CARD_CFG_V50;
        memcpy(lpCardCfg, lpBuffer, sizeof(*lpCardCfg)); //Copy the card information of callback function
		//PostMessage(WM_MSG_ADD_CARDCFG_TOLIST, (WPARAM)lpCardCfg,0);

		char *pCardNo; 
		BYTE byCardType;
		pCardNo = (char *)lpCardCfg->byCardNo; 
		byCardType = lpCardCfg->byCardType;
		//Other processes...
	}
	else if (dwType == NET_SDK_CALLBACK_TYPE_STATUS)//Status value
	{
		DWORD dwStatus = *(DWORD*)lpBuffer;
		if (dwStatus == NET_SDK_CALLBACK_STATUS_SUCCESS)
		{
			bGetCardCfgFinish = TRUE;//Getting card information complated.
			//PostMessage(WM_MSG_GETCARD_FINISH,0,0);
			//Other processes...
		}
		else if ( dwStatus == NET_SDK_CALLBACK_STATUS_FAILED )
		{
			char szCardNumber[ACS_CARD_NO_LEN + 1] = "\0";
			DWORD dwErrCode = *(DWORD*)((char *)lpBuffer + 4); //Error code
			strncpy(szCardNumber,(char*)(lpBuffer) + 8,ACS_CARD_NO_LEN);//Card No.
			printf("GetCard STATUS_FAILED, Error code %d, Card Number %s\n", dwErrCode,  szCardNumber);
			//Other processes...
		}
	}
}

void CALLBACK g_fSetGatewayCardCallback(DWORD dwType, void* lpBuffer, DWORD dwBufLen, void* pUserData)
{
	if (dwType != NET_SDK_CALLBACK_TYPE_STATUS)//Only status will be returned when applying card
	{
		return;
	}

	DWORD dwStatus = *(DWORD*)lpBuffer;//The first 4-byte is status value

	if (dwStatus == NET_SDK_CALLBACK_STATUS_PROCESSING)//Sending
	{   
		char szCardNumber[ACS_CARD_NO_LEN + 1] = "\0";
		strncpy(szCardNumber,(char*)(lpBuffer) + 4,ACS_CARD_NO_LEN);
		printf("SetCard PROCESSING,CardNo: %s\n", szCardNumber);
		//Other processes...
	}
	else if (dwStatus == NET_SDK_CALLBACK_STATUS_FAILED)//Sending failed.
	{
		char szCardNumber[ACS_CARD_NO_LEN + 1] = "\0";
		DWORD dwErrCode = *((DWORD*)lpBuffer + 1);//Error code
		strncpy(szCardNumber,(char*)(lpBuffer) + 8,ACS_CARD_NO_LEN);//Card No.
		printf("SetCard Err:%d,CardNo:%s\n", dwErrCode, szCardNumber);
		//Other processes...
	}
	//The following contents should perfrom stopping remote configuration for twice.
	else if (dwStatus == NET_SDK_CALLBACK_STATUS_SUCCESS)//Sent
	{
        printf("SetCard SUCCESS!");
		bSetCardCfgFinish = TRUE;
		//Other processes...
		//PostMessage(WM_MSG_SETCARD_FINISH,0,0);	
	}
	else if (dwStatus == NET_SDK_CALLBACK_STATUS_EXCEPTION)//Exception
	{
		bSetCardCfgFinish = TRUE;
		//Other processes...
		//PostMessage(WM_MSG_SETCARD_FINISH,0,0);
	}
}

void main()
{
	//---------------------------------------
	//Initialize
	NET_DVR_Init();
	
	//Set connection timeout and reconnection function
	NET_DVR_SetConnectTime(2000, 1);
	NET_DVR_SetReconnect(10000, true);
	
	//---------------------------------------
	//Log in to device
	LONG lUserID;
	NET_DVR_DEVICEINFO_V30 struDeviceInfo;
	lUserID = NET_DVR_Login_V30("192.0.0.64", 8000, "admin", "12345", &struDeviceInfo);
	if (lUserID < 0)
	{
		printf("Login error, %d\n", NET_DVR_GetLastError());
		NET_DVR_Cleanup(); 
		return;
	}
	
	//Get card information---------------------------------
	NET_DVR_CARD_CFG_COND struCond = {0};
          struCond.dwSize  = sizeof(struCond);
          struCond.dwCardNum = 1;//Get the number of cards
          struCond.byCheckCardNo = 1;

	NET_DVR_CARD_CFG_SEND_DATA struSendData = {0}; 
          struSendData.dwSize = sizeof(struSendData);
	m_csCardNo = "12";//Card No.
	strncpy((char *)struSendData.byCardNo, (LPCTSTR)m_csCardNo, ACS_CARD_NO_LEN);

	//Start remote configuration
	m_lGetCardCfgHandle = NET_DVR_StartRemoteConfig(lUserID,NET_DVR_GET_CARD_CFG_V50,&struCond,\
		sizeof(struCond),g_fGetGatewayCardCallback,NULL);
	if (m_lGetCardCfgHandle==-1)
	{
		printf("NET_DVR_StartRemoteConfig fail, error:%d.\n", NET_DVR_GetLastError());
		NET_DVR_Logout(lUserID);
		NET_DVR_Cleanup();
		return;
	}
	//Send search conditions remotely
	if (! NET_DVR_SendRemoteConfig(m_lGetCardCfgHandle, ENUM_ACS_SEND_DATA, (char *)(&struSendData), sizeof(struSendData)) )
	{
		printf("NET_DVR_SendRemoteConfig fail, error:%d.\n", NET_DVR_GetLastError());
		NET_DVR_StopRemoteConfig(m_lGetCardCfgHandle);
		NET_DVR_Logout(lUserID);
		NET_DVR_Cleanup();
		return;
	}
	//Stop remote configuration
	Sleep(1000);
	if (bGetCardCfgFinish)//Stop remote connection if getting card information completed.
	{
		NET_DVR_StopRemoteConfig(m_lGetCardCfgHandle);
	}

	//Apply card information---------------------------------
	NET_DVR_CARD_CFG_COND struCond_set = {0};
          struCond_set.dwSize  = sizeof(struCond_set);
          struCond_set.dwCardNum = 1;//Number of card to apply
          struCond_set.byCheckCardNo = 1;
	struCond_set.wLocalControllerID = 0;//Apply offline card information to distributed access controller No.
                                            //0-access controller
	
	//Start remote configuration
	m_lSetCardCfgHandle = NET_DVR_StartRemoteConfig(lUserID,NET_DVR_SET_CARD_CFG_V50,&struCond_set,\
		sizeof(struCond_set),g_fSetGatewayCardCallback,NULL);
	if (m_lSetCardCfgHandle==-1)
	{
		printf("NET_DVR_StartRemoteConfig fail, error:%d.\n", NET_DVR_GetLastError());
		NET_DVR_Logout(lUserID);
		NET_DVR_Cleanup();
		return;
	}
	
	//Set card information
	LPNET_DVR_CARD_CFG_V50 lpCardCfg =  new NET_DVR_CARD_CFG_V50; 
	lpCardCfg->dwSize = sizeof(NET_DVR_CARD_CFG_V50);
	lpCardCfg->dwModifyParamType = 0x000003FF;//Card information to be edited, represented by bit,
                                                  //each bit refers to one kind of parameter, 0-Not Edit, 1-Edit
	
	m_csCardNo = "12";//Card No.
	strncpy((char *)lpCardCfg->byCardNo, (LPCTSTR)m_csCardNo, ACS_CARD_NO_LEN);
	lpCardCfg->byCardValid = 1;//Card is valid or not: 0-invalid card, 1-valid card
	lpCardCfg->byCardType = 1;//Card type: 1-Normal card (default)
	lpCardCfg->byLeaderCard = 0;//First card or not: 1-Yes, 0-No
	lpCardCfg->byDoorRight[0] = 1;//byDoorRight[0] to byDoorRight[255]: door 1 to door 256, 1-with permission, 0-no permission
	lpCardCfg->byDoorRight[1] = 1;//Door 1 and door 2 are with permission.
	
	lpCardCfg->byBelongGroup[0] = 1;//byBelongGroup[0] to byBelongGroup[127]: array 1 to array 128, 1-in range, 0-not in range
	m_csCardPassword = "12345678";//Card password
	strncpy((char *)lpCardCfg->byCardPassword, (LPCTSTR)m_csCardPassword, CARD_PASSWORD_LEN);
	//Configure the access permission schedule template first.
	lpCardCfg->wCardRightPlan[0][0]=1;//This card is configured with access permission schedule template 1 and 2 for door 1
	lpCardCfg->wCardRightPlan[0][1]=2;
	lpCardCfg->wCardRightPlan[1][0]=3;//This card is configured with access permission schedule template 3 and 4 for door 2
	lpCardCfg->wCardRightPlan[1][1]=4;
	
	lpCardCfg->dwMaxSwipeTime = 0;//Maximum card swiping times, 0-no limit
	lpCardCfg->dwSwipeTime = 0;//Swiped times
	
	lpCardCfg->struValid.byEnable = 1;//Validity duration
	lpCardCfg->struValid.struBeginTime.wYear=2017;//Start time: 2017-01-01 00:00:00
	lpCardCfg->struValid.struBeginTime.byMonth=1;
	lpCardCfg->struValid.struBeginTime.byDay=1;
	lpCardCfg->struValid.struBeginTime.byHour=0;
	lpCardCfg->struValid.struBeginTime.byMinute=0;
	lpCardCfg->struValid.struBeginTime.bySecond=0;
	
	lpCardCfg->struValid.struEndTime.wYear=2018;//End time: 2018-01-01 00:00:00
	lpCardCfg->struValid.struEndTime.byMonth=1;
	lpCardCfg->struValid.struEndTime.byDay=1;
	lpCardCfg->struValid.struEndTime.byHour=0;
	lpCardCfg->struValid.struEndTime.byMinute=0;
	lpCardCfg->struValid.struEndTime.bySecond=0;
	
	//Send card information remotely
	if (!NET_DVR_SendRemoteConfig(m_lSetCardCfgHandle,ENUM_ACS_SEND_DATA, (char *)lpCardCfg ,sizeof(*lpCardCfg)))
    {
		printf("NET_DVR_SendRemoteConfig fail, error:%d.\n", NET_DVR_GetLastError());
		NET_DVR_StopRemoteConfig(m_lSetCardCfgHandle);
		NET_DVR_Logout(lUserID);
		NET_DVR_Cleanup();
		return;   
    }
	//Stop remote configuration
	Sleep(1000);
	if (bSetCardCfgFinish)//Stop remote configuration when applied or callback exception.
	{
		NET_DVR_StopRemoteConfig(m_lSetCardCfgHandle);
	}
	
	//---------------------------------------
	//Exit
	Sleep(5000);
	
	//Log out
	NET_DVR_Logout(lUserID);
	//Release SDK resources
	NET_DVR_Cleanup();
	return;
}

Call NET_DVR_Logout and NET_DVR_Cleanup to log out and release the resource.