A high-performance Node.js middleware server designed to interface with biometric attendance devices (Biomax, ZKTeco, RealAnd, FK-Series) using the FK Web Protocol. This server acts as a bridge, parsing proprietary binary/JSON hybrid payloads and storing clean attendance data into Firebase Firestore.
Many biometric devices use a variation of the ADMS/FK protocol which communicates over HTTP but follows non-standard behaviors. This project solves the common pitfalls of "Connection Refused", "Infinite Loops", and "Data Mapping" issues that occur when using standard web servers.
Problem: The device shows "Network OK" but no data reaches the server.
Discovery: Using tcpdump, we found the device is hardcoded to POST /hdata.aspx. Most modern frameworks expect RESTful routes.
Solution: Implemented a specific handler for /hdata.aspx and configured the server to handle application/octet-stream via raw buffer processing.
Problem: The device sends the same attendance record every few seconds, never clearing its internal memory. Root Cause: The device requires a specific Acknowledgement (ACK) string and a strict Connection: close header. If it receives a standard HTTP 200 without these, it assumes the packet was lost and retries indefinitely. Solution:
- Differentiated responses:
result=OKfor logs/enrollments andOKfor heartbeats. - Forced
Connection: closeto tell the device the transaction is complete. - Stripped unnecessary headers (
Date,ETag,X-Powered-By) that legacy firmware often chokes on.
Problem: Every punch (Check-In, Check-Out, Break) arrived with the same raw code 16777216.
Discovery: The io_mode is a Bitmask Integer, not a simple index. Pressing F1/F2 keys changes these bits.
Solution: Decoded the bitmask values through real-time tcpdump analysis during physical device testing.
| Device Action | Raw io_mode |
Mapped Status |
|---|---|---|
| Default / F1 | 16777216 |
Check-In |
| F2 / Right Arrow | 33554432 |
Check-Out |
| Break In | 50331648 |
Break-In |
| Break Out | 67108864 |
Break-Out |
| Overtime In | 83886080 |
Overtime-In |
| Overtime Out | 100663296 |
Overtime-Out |
- Target URL:
/hdata.aspx - Content-Type:
application/octet-stream - Payload: Hybrid (Binary Header + JSON String)
- Handshake: HTTP/1.1 or 1.0 (requires strict closure)
- Headers:
cmd_id(Action type),dev_id(Serial Number)
-
Clone the repository:
git clone https://github.com/CryptoMaN-Rahul/biometric-attendance-server-nodejs cd biometric-attendance-server-nodejs -
Install dependencies:
npm install
-
Firebase Setup:
- Create a Firebase project.
- Download your
serviceAccountKey.json. - Update the code with your database reference.
To see exactly what the device is sending in real-time:
Monitor Raw Traffic:
sudo tcpdump -i any port 3000 -A -s 0Filter for Specific Actions:
sudo tcpdump -i any port 3000 -A -s 0 -l | grep --line-buffered -A 10 "RTLogSendAction"The server handles requests by:
- Buffering the binary stream.
- Extracting the JSON payload using
{}delimiters. - Mapping the
io_modeto a readable status. - Sending the correct ACK to clear the device buffer.
// Critical ACK Logic
res.writeHead(200, {
'Content-Type': 'text/plain',
'Connection': 'close'
});
res.end(responseText); // "result=OK" or "OK"