Bulk User Submission

The Protege WX system was originally designed to allow users to be submitted one by one using text-based parameters. This can be a very slow process if adding several thousand users programmatically, so a parallel system has been introduced which allows for a table of users to be submitted in a binary format.

Update

When submitting a bulk user table use an HTTP POST method with the following included as the text:

Copy
Command&Type=Submit&SubType=GXT_USERS_BLOB_TBL&*binary_data*

The binary_data is the binary table data described below. The binary data must be encoded as hexadecimal string (e.g. C800000035F40000C9000000AA020000A286...).

A maximum of 350 records can be submitted per post.

The user Record IDs must be in monotonic order from lowest to highest. The submitted block will be inserted into the database, overwriting any records that already exist in the ID range specified by the table. If any Record IDs are left 'blank' in the table, existing records in the database will be deleted.

For example, if the users 1,2,3,4,5,6,7 were already in the database and a table with users 2,4, and 6 was submitted, then the database would contain users 1,2,4,6,7 (records 3 and 5 have been overwritten with blank data).

User name fields (First Name, Last Name and Display Name) have a limit of 32 characters each. Bulk user submission does not prevent you from submitting names longer than this limit, but future changes to user records will be rejected until the names are shortened. To avoid this, restrict bulk user submissions to the same name length rules as the standard Submit command.

Details

When retrieving a bulk user table use an HTTP GET method with the following included as the text:

Copy
Request&Type=Detail&SubType=GXT_USERS_BLOB_TBL&RecId=123&UserCount=20

The response will be the binary data (hexadecimal encoded string) of a user table.

The RecId parameter defines the first user to include in the table. If that user is not found then the table will start at the next programmed Record ID.

The UserCount defines how many users to include in the table, up to a maximum of 350.

Table Structure

The users table is formatted as a sequence of Type, Length and Value (TLV) triplets. The type and length are always 32 bit values. The value's size depends on the type. All values are presented in little endian format.

When first learning how to generate a user table it may be useful to initially extract a table using the request function and examine the structure.

When submitting a user table a check is performed on the table's structure and it will be rejected if errors are found. However, this check cannot cover every possible inconsistency and the responsibility is on the integrator to ensure that the tables are correctly formed. Failure to do so could result in database corruption.

The types used in table are listed below.

Table Header

32 bit reference value.

e.g. A GXT_USERS_TBL which is 0x0000A0D6 bytes long (including the 8 bytes of type and length):

Type

Length

Value

C8 00 00 00

D6 A0 00 00

the table

Long

32 bit value.

e.g. GXF_USERS_DEFAULTLANGUAGE = 0 (English):

Type

Length

Value

48 00 64 00

0C 00 00 00

00 00 00 00

Boolean

1 bit value (stored as one byte).

e.g. GXF_USERS_TRACEUSER = true:

Type

Length

Value

34 00 64 00

09 00 00 00

01

String

Unicode string. 4 byte character count followed by 2 bytes for each character.

e.g. GXF_USERS_NAME = "Bob":

Type

Length

Value

04 00 64 00

12 00 00 00

03 00 00 00 00 42 00 6F 00 62

Date/Time

6 byte packed time value:

  • Byte 0 = Year

  • Byte 1 = Month

  • Byte 2 = Day

  • Byte 3 = Hour

  • Byte 4 = Minute

  • Byte 5 = Second

e.g. Access level start time = midnight on the 10th of September 2018:

Type

Length

Value

66 00 00 00

0E 00 00 00

12 09 0A 00 00 00

If the year value is set of 0xFF then this is a special code which tells the Protege WX UI that the time has never been set (for display purposes). From an operational point of view there are no special date/time codes.

Definitions

Listed below are the types that make up the data in a user table.

Description

Value

Type

GXT_USERS_TBL

(0x000000c8)

Table header

GXT_USERS_INST

(0x000000c9)

Table header

GXF_RECORD_ID

(0x000186a2)

Long

GXF_CHILDRECORD_ID

(0x000186a0)

Long

GXF_PARENTRECORD_ID

(0x000186a1)

Long

GXC_USERACCESSLEVELGROUPDATA_TBL

(0x00000000)

Table header

GXC_USERACCESSLEVELGROUPDATA_INST

(0x00000001)

Table header

GXF_USERACCESSLEVELGROUPDATA_SITE

(0x00000064)

Long

GXF_USERACCESSLEVELGROUPDATA_USERACCESSLEVEL

(0x00000065)

Long

GXF_USERACCESSLEVELGROUPDATA_USERACCESSLEVELSTART

(0x00000066)

Date/Time

GXF_USERACCESSLEVELGROUPDATA_USERACCESSLEVELEND

(0x00000067)

Date/Time

GXF_USERACCESSLEVELGROUPDATA_USERACCESSLEVELEXPIRE

(0x00000068)

Boolean

GXF_USERACCESSLEVELGROUPDATA_USERACCESSLEVELSCHEDULE

(0x00000069)

Long

GXC_USERCARDNUMBERGROUPDATA_TBL

(0x00000002)

Table header

GXC_USERCARDNUMBERGROUPDATA_INST

(0x00000003)

Table header

GXF_USERCARDNUMBERGROUPDATA_SITE

(0x000000c8)

Long

GXF_USERCARDNUMBERGROUPDATA_CARDNUMBER

(0x000000c9)

String

GXF_USERCARDNUMBERGROUPDATA_FAMILYNUMBER

(0x000000ca)

String

GXF_USERCARDNUMBERGROUPDATA_CARDDISABLED

(0x000000cb)

Boolean

GXF_USERCARDNUMBERGROUPDATA_INACTIVITYISACTIVE

(0x000000cd)

Not used

GXF_USERCARDNUMBERGROUPDATA_INACTIVITYACTION

(0x000000ce)

Not used

GXF_USERCARDNUMBERGROUPDATA_INACTIVITYPERIOD

(0x000000cf)

Not used

GXF_USERCARDNUMBERGROUPDATA_LASTUSED

(0x000000d0)

Not used

GXC_USERAREAGROUPDATA_TBL

(0x00000004)

Table header

GXC_USERAREAGROUPDATA_INST

(0x00000005)

Table header

GXF_USERAREAGROUPDATA_SITE

(0x00000064)

Long

GXF_USERAREAGROUPDATA_USERAREAGROUP

(0x00000065)

Long

GXC_USERCREDENTIALGROUPDATA_TBL

(0x00000010)

Table header

GXC_USERCREDENTIALGROUPDATA_INST

(0x00000011)

Table header

GXF_USERCREDENTIALGROUPDATA_SITE

(0x00000384)

Long

GXF_USERCREDENTIALGROUPDATA_CREDENTIAL

(0x00000385)

String

GXF_USERCREDENTIALGROUPDATA_TYPE

(0x00000386)

Long

GXF_USERCREDENTIALGROUPDATA_DISABLED

(0x00000387)

Boolean

GXF_USERS_LASTNAME

(0x00640001)

String

GXF_USERS_FIRSTNAME

(0x00640002)

String

GXF_USERS_NAME

(0x00640003)

String

GXF_USERS_NAME2

(0x00640004)

String

GXF_USERS_USERACCESSLEVEL

(0x00640017)

Not used

GXF_USERS_LASTMODIFIED

(0x00640018)

Not used

GXF_USERS_SHOWAGREETINGMESSAGETOUSER

(0x0064001a)

Boolean

GXF_USERS_GODIRECTLYTOTHEMENUONLOGIN

(0x0064001b)

Boolean

GXF_USERS_USERCANACKNOWLEDGEALARMMEMORY

(0x0064001c)

Boolean

GXF_USERS_SHOWALARMMEMORYONLOGIN

(0x0064001d)

Boolean

GXF_USERS_TURNOFFTHEPRIMARYAREAIFUSERHASACCESSONLOGIN

(0x0064001e)

Boolean

GXF_USERS_TURNOFFTHEUSERAREAONLOGINIFUSERHASACCESS

(0x0064001f)

Boolean

GXF_USERS_ACKNOWLEDGESYSTEMTROUBLES

(0x00640020)

Boolean

GXF_USERS_USERHASSUPERRIGHTSANDCANOVERRIDEANTIPASSBACK

(0x00640023)

Boolean

GXF_USERS_USERCANMODIFYTHEIROWNCODE

(0x00640024)

Boolean

GXF_USERS_USEROPERATESADAFUNCTION

(0x00640025)

Boolean

GXF_USERS_USERLOITEREXPIRYCOUNTENABLED

(0x00640026)

Boolean

GXF_USERS_USERCANLOGINREMOTELY

(0x00640027)

Boolean

GXF_USERS_USERISADURESSUSER

(0x00640028)

Boolean

GXF_USERS_EXPIRYDATE

(0x0064002c)

Date/Time

GXF_USERS_EXPIRYTIME

(0x0064002d)

Date/Time

GXF_USERS_DOORGROUPEXCEPTION

(0x0064002e)

Not used

GXF_USERS_PINNUMBER

(0x0064002f)

String

GXF_USERS_USERCARDNUMBER

(0x00640030)

Not used

GXF_USERS_IMAGEID

(0x00640031)

Not used

GXF_USERS_MERGE

(0x00640032)

Not used

GXF_USERS_DISABLEUSER

(0x00640033)

Boolean

GXF_USERS_TRACEUSER

(0x00640034)

Boolean

GXF_USERS_BADGENUMBER

(0x00640035)

Not used

GXF_USERS_BADGETYPE

(0x00640036)

Not used

GXF_USERS_SERVICENAME

(0x00640037)

Not used

GXF_USERS_SERVICENUMBER

(0x00640038)

Not used

GXF_USERS_EMPLOYEEFUNCTION

(0x00640039)

Not used

GXF_USERS_LICENSENUMBER

(0x0064003a)

Not used

GXF_USERS_UNION

(0x0064003b)

Not used

GXF_USERS_SITE

(0x0064003c)

Not used

GXF_USERS_DATEOFBADGEPRODUCTION

(0x0064003d)

Not used

GXF_USERS_EXPIRATIONDATEOFBADGE

(0x0064003e)

Not used

GXF_USERS_CUSTOMFIELD1

(0x0064003f)

String

GXF_USERS_CUSTOMFIELD2

(0x00640040)

String

GXF_USERS_CUSTOMFIELD3

(0x00640041)

String

GXF_USERS_CUSTOMFIELD4

(0x00640042)

String

GXF_USERS_CUSTOMFIELD5

(0x00640043)

String

GXF_USERS_CUSTOMNOTEFIELD1

(0x00640044)

String

GXF_USERS_CUSTOMNOTEFIELD2

(0x00640045)

String

GXF_USERS_CARDNUMBER

(0x00640046)

Not used

GXF_USERS_CARDTYPE

(0x00640047)

Not used

GXF_USERS_DEFAULTLANGUAGE

(0x00640048)

Long

GXF_USERS_REARMAREAINSTAYMODE

(0x0064004A)

Boolean

GXF_USERS_USERAREA

(0x0064004B)

Long

GXF_USERS_USERAREAGROUP

(0x0064004C)

Long

GXF_USERS_EXPIRYDATEVALID

(0x00640051)

Boolean

GXF_USERS_STARTDATE

(0x00640052)

Date/Time

GXF_USERS_STARTDATEVALID

(0x00640053)

Boolean

GXF_USERS_DUALCUSTODYMASTER

(0x00640056)

Boolean

GXF_USERS_DUALCUSTODYPROVIDER

(0x00640057)

Boolean

GXF_USERS_REPORTINGID

(0x00640087)

Long

GXF_USERS_SALTOOVERRIDEPRIVACY

(0x00640088)

Not used

GXF_USERS_SALTOOVERRIDELOCKDOWN

(0x00640089)

Not used

GXF_USERS_SALTOLOCKDOWNENABLED

(0x0064008A)

Not used

GXF_USERS_TREATPINPLUSONEASDURESS

(0x0064008C)

Boolean

GXF_USERS_CONDOUSERCANONLYARM

(0x0064008D)

Boolean

GXF_USERS_CONDOUSERCANVIEWUSERMENU

(0x0064008E)

Boolean

GXF_USERS_CONDOUSERDISARMONSINGLEBADGE

(0x0064008F)

Boolean

GXF_USERS_CONDOUSERARMON3BADGE

(0x00640090)

Boolean

GXF_USERS_CONDOUSER3BADGELATCHDOORTOGGLE

(0x00640091)

Boolean

GXF_USERS_CONDOUSER3BADGELATCHDOOR2HOURS

(0x00640092)

Boolean

GXF_USERS_CONDOUSER3BADGELATCHDOOR4HOURS

(0x00640093)

Boolean

GXF_USERS_CONDOUSER3BADGELATCHDOOR8HOURS

(0x00640094)

Boolean

GXF_USERS_PHONEEXTENSION

(0x00640095)

Long

GXF_USERS_PHONEEXTENSION_STRING

(0x00640096)

String

GXF_USERS_COMPANYNAME

(0x00640097)

String

GXF_USERS_HLI_VIP

(0x00640098)

Boolean

GXF_USERS_HLI_VERTIGO

(0x00640099)

Boolean

GXF_USERS_HLI_SPLIT_GROUP

(0x0064009A)

Boolean

GXF_USERS_HLI_VERTIGO2

(0x0064009B)

Boolean

GXF_USERS_HLI_CART_SVC

(0x0064009C)

Boolean

GXF_USERS_HLI_CIM_OVERRIDE

(0x0064009D)

Boolean

GXF_USERS_DATEOFLASTPINUPDATE

(0x006400A5)

Date/Time

Examples

Below is the first part of a user record with a description of what each part means in the right hand column. Note that Protege WX user records are compatible with Protege GX user records, so can contain elements relevant only to Protege GX. For example Child Record ID and Parent Record ID may be present in the records that are extracted. These can safely be ignored and are not required when submitting new records.

Record

Description

c8 00 00 00 16 05 00 00

User table, 1302 bytes long

c9 00 00 00 0e 05 00 00

Instance of one user, 1294 bytes long

a2 86 01 00 0c 00 00 00 02 00 00 00

Record ID = 2

a1 86 01 00 0c 00 00 00 05 00 00 00

Parent Record ID = 5 (can be ignored / omitted)

00 00 00 00 da 00 00 00

Access level table header, length = 218 bytes

01 00 00 00 69 00 00 00

Access level Instance, length = 105 bytes

a0 86 01 00 0c 00 00 00 5a 0e 00 00

Child Record ID = 3674 (can be ignored / omitted)

a1 86 01 00 0c 00 00 00 05 00 00 00

Parent Record ID = 5 (can be ignored / omitted)

64 00 00 00 0c 00 00 00 05 00 00 00

Site = 5 (can be ignored / omitted)

65 00 00 00 0c 00 00 00 58 00 00 00

User's access level = 88

66 00 00 00 0e 00 00 00 12 09 0a 00 00 00

Access level start time

67 00 00 00 0e 00 00 00 12 09 0a 00 00 00

Access level end time

68 00 00 00 09 00 00 00 00

Access level expires = false

69 00 00 00 0c 00 00 00 ff ff ff ff

Access level schedule = not set

01 00 00 00 69 00 00 00

Access level Instance, length = 105 bytes

a0 86 01 00 0c 00 00 00 5a 0e 00 00

Child Record ID = 3674 (can be ignored / omitted)

a1 86 01 00 0c 00 00 00 05 00 00 00

Parent Record ID = 5 (can be ignored / omitted)

64 00 00 00 0c 00 00 00 05 00 00 00

Site = 5 (can be ignored / omitted)

65 00 00 00 0c 00 00 00 57 00 00 00

Users access level = 87

66 00 00 00 0e 00 00 00 12 09 0b 00 00 00

Access level start time

67 00 00 00 0e 00 00 00 12 09 0b 00 00 00

Access level end time

68 00 00 00 09 00 00 00 00

Access level expires = false

69 00 00 00 0c 00 00 00 ff ff ff ff

Access level schedule = not set

02 00 00 00 72 01 00 00

Card number table, length 370

03 00 00 00 74 00 00 00

Card Instance, length 116

a0 86 01 00 0c 00 00 00 5a 0e 00 00

Child Record Id = 3674 (can be ignored / omitted)

a1 86 01 00 0c 00 00 00 05 00 00 00

Parent Record Id = 5 (can be ignored / omitted)

c8 00 00 00 0c 00 00 00 05 00 00 00

Site = 5 (can be ignored / omitted)

c9 00 00 00 0e 00 00 00 01 00 00 00 34 00

Card code, 1 character string = "4"

ca 00 00 00 10 00 00 00 02 00 00 00 31 00 30 00

Site code, 2 character string = "10"

cb 00 00 00 09 00 00 00 00

Card disabled = false

cd 00 00 00 09 00 00 00 00

Inactivity = false (can be ignored / omitted)

ce 00 00 00 0c 00 00 00 01 00 00 00

Inactivity action = 1 (can be ignored / omitted)

cf 00 00 00 0c 00 00 00 00 00 00 00

Inactivity period = 0 (can be ignored / omitted)

03 00 00 00 7c 00 00 00

Next card instance