libSNAP v1.0.0
Open source C/C++ library for the Scaleable Node Address Protocol (SNAP)
snap.h
Go to the documentation of this file.
1/*
2Copyright (c) 2022 Lucas Jadilo
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20SOFTWARE.
21*/
22
29#ifndef SNAP_H_
30#define SNAP_H_
31
32#ifdef __cplusplus
33 extern "C" {
34#endif
35
45/******************************************************************************/
46/* Public Includes */
47/******************************************************************************/
48
49
50#include <stdint.h>
51#include <stdbool.h>
52
53
54/******************************************************************************/
55/* Public Macros */
56/******************************************************************************/
57
58
68#define SNAP_ERROR_NULL_FRAME (-1)
69#define SNAP_ERROR_NULL_BUFFER (-2)
70#define SNAP_ERROR_SHORT_BUFFER (-3)
71#define SNAP_ERROR_UNKNOWN_FORMAT (-4)
72#define SNAP_ERROR_FRAME_FORMAT (-5)
73#define SNAP_ERROR_SHORT_FRAME (-6)
74#define SNAP_ERROR_FIELD_TYPE (-7)
82#define SNAP_HDB2_DAB_MASK (0x03U)
83#define SNAP_HDB2_DAB_POS (6U)
85#define SNAP_HDB2_SAB_MASK (0x03U)
86#define SNAP_HDB2_SAB_POS (4U)
88#define SNAP_HDB2_PFB_MASK (0x03U)
89#define SNAP_HDB2_PFB_POS (2U)
91#define SNAP_HDB2_ACK_MASK (0x03U)
92#define SNAP_HDB2_ACK_POS (0U)
100#define SNAP_HDB1_CMD_MASK (0x01U)
101#define SNAP_HDB1_CMD_POS (7U)
103#define SNAP_HDB1_EDM_MASK (0x07U)
104#define SNAP_HDB1_EDM_POS (4U)
106#define SNAP_HDB1_NDB_MASK (0x0FU)
107#define SNAP_HDB1_NDB_POS (0U)
115#define SNAP_GET_BITS(integer, mask, pos) (((unsigned int)(integer) >> (pos)) & (mask))
117#define SNAP_HDB2(pByteArray) ((pByteArray)[SNAP_INDEX_HDB2])
118#define SNAP_HDB1(pByteArray) ((pByteArray)[SNAP_INDEX_HDB1])
120#define SNAP_HDB2_DAB(pByteArray) (SNAP_GET_BITS(SNAP_HDB2(pByteArray), SNAP_HDB2_DAB_MASK, SNAP_HDB2_DAB_POS))
121#define SNAP_HDB2_SAB(pByteArray) (SNAP_GET_BITS(SNAP_HDB2(pByteArray), SNAP_HDB2_SAB_MASK, SNAP_HDB2_SAB_POS))
122#define SNAP_HDB2_PFB(pByteArray) (SNAP_GET_BITS(SNAP_HDB2(pByteArray), SNAP_HDB2_PFB_MASK, SNAP_HDB2_PFB_POS))
123#define SNAP_HDB2_ACK(pByteArray) (SNAP_GET_BITS(SNAP_HDB2(pByteArray), SNAP_HDB2_ACK_MASK, SNAP_HDB2_ACK_POS))
125#define SNAP_HDB1_CMD(pByteArray) (SNAP_GET_BITS(SNAP_HDB1(pByteArray), SNAP_HDB1_CMD_MASK, SNAP_HDB1_CMD_POS))
126#define SNAP_HDB1_EDM(pByteArray) (SNAP_GET_BITS(SNAP_HDB1(pByteArray), SNAP_HDB1_EDM_MASK, SNAP_HDB1_EDM_POS))
127#define SNAP_HDB1_NDB(pByteArray) (SNAP_GET_BITS(SNAP_HDB1(pByteArray), SNAP_HDB1_NDB_MASK, SNAP_HDB1_NDB_POS))
135#define SNAP_SIZE_SYNC (1U)
136#define SNAP_SIZE_HDB2 (1U)
137#define SNAP_SIZE_HDB1 (1U)
138#define SNAP_SIZE_HEADER (SNAP_SIZE_HDB2 + SNAP_SIZE_HDB1)
139#define SNAP_SIZE_DATA(pByteArray) (snap_getDataSizeFromNdb(SNAP_HDB1_NDB(pByteArray)))
140#define SNAP_SIZE_HASH(pByteArray) (snap_getHashSizeFromEdm(SNAP_HDB1_EDM(pByteArray)))
141#define SNAP_MIN_SIZE_FRAME (SNAP_SIZE_SYNC + SNAP_SIZE_HEADER)
142#define SNAP_MAX_SIZE_FRAME (528U)
144#ifdef SNAP_SIZE_USER_HASH
145 #if (SNAP_SIZE_USER_HASH < 0) || (SNAP_SIZE_USER_HASH > 4)
146 #error Invalid user hash size! It must be an integer from 0 to 4 (bytes).
147 #endif
148#else
149 #define SNAP_SIZE_USER_HASH (0U)
150#endif
151
158#define SNAP_INDEX_SYNC (0U)
159#define SNAP_INDEX_HDB2 (1U)
160#define SNAP_INDEX_HDB1 (2U)
161#define SNAP_INDEX_DAB (3U)
162#define SNAP_INDEX_SAB(pByteArray) (SNAP_INDEX_DAB + SNAP_HDB2_DAB(pByteArray))
163#define SNAP_INDEX_PFB(pByteArray) (SNAP_INDEX_SAB(pByteArray) + SNAP_HDB2_SAB(pByteArray))
164#define SNAP_INDEX_DATA(pByteArray) (SNAP_INDEX_PFB(pByteArray) + SNAP_HDB2_PFB(pByteArray))
165#define SNAP_INDEX_HASH(pByteArray) (SNAP_INDEX_DATA(pByteArray) + SNAP_SIZE_DATA(pByteArray))
173#define SNAP_BROADCAST_ADDRESS (0U)
174#define SNAP_SYNC (0x54U)
175#define SNAP_PADDING (0x00U)
189#define snap_getSync() (SNAP_SYNC)
190#define snap_getHdb2(pFrame) (SNAP_HDB2((pFrame)->buffer))
191#define snap_getHdb1(pFrame) (SNAP_HDB1((pFrame)->buffer))
192#define snap_getDab(pFrame) (SNAP_HDB2_DAB((pFrame)->buffer))
193#define snap_getSab(pFrame) (SNAP_HDB2_SAB((pFrame)->buffer))
194#define snap_getPfb(pFrame) (SNAP_HDB2_PFB((pFrame)->buffer))
195#define snap_getAck(pFrame) (SNAP_HDB2_ACK((pFrame)->buffer))
196#define snap_getCmd(pFrame) (SNAP_HDB1_CMD((pFrame)->buffer))
197#define snap_getEdm(pFrame) (SNAP_HDB1_EDM((pFrame)->buffer))
198#define snap_getNdb(pFrame) (SNAP_HDB1_NDB((pFrame)->buffer))
199#define snap_getHeader(pFrame, pHeader) (snap_getField(pFrame, pHeader, SNAP_FIELD_HEADER))
200#define snap_getDestAddress(pFrame, pDestAddr) (snap_getField(pFrame, pDestAddr, SNAP_FIELD_DEST_ADDRESS))
201#define snap_getSourceAddress(pFrame, pSourceAddr) (snap_getField(pFrame, pSourceAddr, SNAP_FIELD_SOURCE_ADDRESS))
202#define snap_getProtocolFlags(pFrame, pFlags) (snap_getField(pFrame, pFlags, SNAP_FIELD_PROTOCOL_FLAGS))
203#define snap_getData(pFrame, pData) (snap_getField(pFrame, pData, SNAP_FIELD_DATA))
204#define snap_getHash(pFrame, pHash) (snap_getField(pFrame, pHash, SNAP_FIELD_HASH))
205#define snap_getDataPtr(pFrame) ((pFrame)->buffer + SNAP_INDEX_DATA((pFrame)->buffer))
206#define snap_getBufferPtr(pFrame) ((pFrame)->buffer)
207#define snap_getStatus(pFrame) ((pFrame)->status)
215#define snap_getSyncIndex() (SNAP_INDEX_SYNC)
216#define snap_getHdb2Index() (SNAP_INDEX_HDB2)
217#define snap_getHdb1Index() (SNAP_INDEX_HDB1)
218#define snap_getHeaderIndex() (SNAP_INDEX_HDB2)
219#define snap_getDestAddrIndex() (SNAP_INDEX_DAB)
220#define snap_getSourceAddrIndex(pFrame) (SNAP_INDEX_SAB((pFrame)->buffer))
221#define snap_getProtFlagsIndex(pFrame) (SNAP_INDEX_PFB((pFrame)->buffer))
222#define snap_getDataIndex(pFrame) (SNAP_INDEX_DATA((pFrame)->buffer))
223#define snap_getHashIndex(pFrame) (SNAP_INDEX_HASH((pFrame)->buffer))
231#define snap_getSyncSize() (SNAP_SIZE_SYNC)
232#define snap_getHdb2Size() (SNAP_SIZE_HDB2)
233#define snap_getHdb1Size() (SNAP_SIZE_HDB1)
234#define snap_getHeaderSize() (SNAP_SIZE_HEADER)
235#define snap_getDestAddrSize(pFrame) (SNAP_HDB2_DAB((pFrame)->buffer))
236#define snap_getSourceAddrSize(pFrame) (SNAP_HDB2_SAB((pFrame)->buffer))
237#define snap_getProtFlagsSize(pFrame) (SNAP_HDB2_PFB((pFrame)->buffer))
238#define snap_getDataSize(pFrame) (SNAP_SIZE_DATA((pFrame)->buffer))
239#define snap_getHashSize(pFrame) (SNAP_SIZE_HASH((pFrame)->buffer))
240#define snap_getFrameSize(pFrame) ((pFrame)->size)
241#define snap_getBufferSize(pFrame) ((pFrame)->maxSize)
242#define snap_getFullFrameSize(pFrame) (SNAP_INDEX_HASH((pFrame)->buffer) + SNAP_SIZE_HASH((pFrame)->buffer))
251/******************************************************************************/
252/* Public Types */
253/******************************************************************************/
254
255
266{
272 SNAP_FIELD_HASH = 5
274
278typedef enum snap_hdb2_dab_t
279{
285
289typedef enum snap_hdb2_sab_t
290{
296
300typedef enum snap_hdb2_pfb_t
301{
307
312typedef enum snap_hdb2_ack_t
313{
319
330typedef enum snap_hdb1_cmd_t
331{
335
340typedef enum snap_hdb1_edm_t
341{
352
356typedef enum snap_hdb1_ndb_t
357{
375
379typedef enum snap_status_t
380{
387
391typedef struct snap_header_t
392{
393 // HDB2
394 unsigned int dab : 2;
395 unsigned int sab : 2;
396 unsigned int pfb : 2;
397 unsigned int ack : 2;
398 // HDB1
399 unsigned int cmd : 1;
400 unsigned int edm : 3;
401 unsigned int ndb : 4;
403
407typedef struct snap_fields_t
408{
409 uint8_t *data;
410 uint32_t destAddress;
411 uint32_t sourceAddress;
412 uint32_t protocolFlags;
414 uint16_t dataSize;
417
421typedef struct snap_frame_t
422{
423 uint8_t *buffer;
424 uint16_t maxSize;
425 uint16_t size;
426 int8_t status;
428
434/******************************************************************************/
435/* Public Function Declarations */
436/******************************************************************************/
437
438
447int16_t snap_init(snap_frame_t *frame, uint8_t *buffer, uint16_t maxSize);
448
449void snap_reset(snap_frame_t *frame);
450
451int8_t snap_decode(snap_frame_t *frame, uint8_t newByte);
452
453int8_t snap_encapsulate(snap_frame_t *frame, snap_fields_t *fields);
454
455int16_t snap_getField(const snap_frame_t *frame, void *fieldContent, uint8_t fieldType);
456
457int8_t snap_calculateHash(const snap_frame_t *frame, uint32_t *hash);
458
465uint16_t snap_removePaddingBytes(uint8_t *data, uint16_t size, bool paddingAfter);
466
467uint8_t snap_getNdbFromDataSize(uint16_t dataSize);
468
469uint16_t snap_getDataSizeFromNdb(uint8_t ndb);
470
471uint8_t snap_getHashSizeFromEdm(uint8_t edm);
472
473uint8_t snap_calculateChecksum8(const uint8_t *data, uint16_t size);
474
475uint8_t snap_calculateCrc8(const uint8_t *data, uint16_t size);
476
477uint16_t snap_calculateCrc16(const uint8_t *data, uint16_t size);
478
479uint32_t snap_calculateCrc32(const uint8_t *data, uint16_t size);
480
481uint32_t snap_calculateUserHash(const uint8_t *data, uint16_t size);
482
489#ifdef __cplusplus
490 }
491#endif
492
493#endif // SNAP_H_
494
495/******************************** END OF FILE *********************************/
int8_t snap_encapsulate(snap_frame_t *frame, snap_fields_t *fields)
Encapsulate a new frame into the buffer (if there is enough space). Update the frame status and size ...
Definition: snap.c:180
uint16_t snap_calculateCrc16(const uint8_t *data, const uint16_t size)
Calculate the 16-bit CRC of a byte array.
Definition: snap.c:599
uint16_t snap_getDataSizeFromNdb(const uint8_t ndb)
Get the number of data bytes based on the NDB bits of the HDB1 byte.
Definition: snap.c:472
void snap_reset(snap_frame_t *frame)
Reset the frame size and status. The other variables of the frame remain unchanged.
Definition: snap.c:102
int16_t snap_getField(const snap_frame_t *frame, void *fieldContent, const uint8_t fieldType)
Get the content of a selected frame field.
Definition: snap.c:284
uint16_t snap_removePaddingBytes(uint8_t *data, uint16_t size, const bool paddingAfter)
Remove the padding bytes (SNAP_PADDING) of a frame payload (if there are any).
Definition: snap.c:423
uint8_t snap_calculateCrc8(const uint8_t *data, const uint16_t size)
Calculate the 8-bit CRC of a byte array.
Definition: snap.c:526
uint32_t snap_calculateUserHash(const uint8_t *data, const uint16_t size)
Calculate the hash value of a byte array using a user-defined algorithm.
Definition: snap.c:768
uint32_t snap_calculateCrc32(const uint8_t *data, const uint16_t size)
Calculate the 32-bit CRC of a byte array.
Definition: snap.c:679
uint8_t snap_calculateChecksum8(const uint8_t *data, const uint16_t size)
Calculate the 8-bit checksum of a byte array.
Definition: snap.c:496
int16_t snap_init(snap_frame_t *frame, uint8_t *buffer, const uint16_t maxSize)
Initialize the frame structure.
Definition: snap.c:81
uint8_t snap_getHashSizeFromEdm(const uint8_t edm)
Get the hash value size of the frame based on the EDM bits of the HDB1 byte.
Definition: snap.c:484
int8_t snap_calculateHash(const snap_frame_t *frame, uint32_t *hash)
Select the error detection method based on the EDM bits and calculate the hash value of a frame.
Definition: snap.c:369
uint8_t snap_getNdbFromDataSize(const uint16_t dataSize)
Get the NDB bits of the HDB1 byte based on the number of data bytes (with or without padding bytes).
Definition: snap.c:455
int8_t snap_decode(snap_frame_t *frame, const uint8_t newByte)
Detect, decode, validate and store a frame, one byte at a time.
Definition: snap.c:119
snap_status_t
Values for the frame status. The frame structure will always be in one of these states.
Definition: snap.h:380
snap_hdb2_dab_t
Values for the DAB field of the HDB2 header byte. It defines the number of destination address bytes.
Definition: snap.h:279
snap_hdb1_edm_t
Values for the EDM field of the HDB1 header byte. It defines the error detection method used on the f...
Definition: snap.h:341
snap_fieldType_t
Values that identify each field of a frame.
Definition: snap.h:266
snap_hdb2_pfb_t
Values for the PFB field of the HDB2 header byte. It defines the number of protocol specific flags by...
Definition: snap.h:301
snap_hdb1_cmd_t
Values for the CMD field of the HDB1 header byte. It indicates whether the command mode is enabled or...
Definition: snap.h:331
snap_hdb2_ack_t
Values for the ACK field of the HDB2 header byte. It defines if the sending node requests an ACK/NACK...
Definition: snap.h:313
snap_hdb2_sab_t
Values for the SAB field of the HDB2 header byte. It defines the number of source address bytes.
Definition: snap.h:290
snap_hdb1_ndb_t
Values for the NDB field of the HDB1 header byte. It defines the number of data/payload bytes.
Definition: snap.h:357
@ SNAP_STATUS_VALID
Definition: snap.h:383
@ SNAP_STATUS_INCOMPLETE
Definition: snap.h:382
@ SNAP_STATUS_ERROR_OVERFLOW
Definition: snap.h:385
@ SNAP_STATUS_ERROR_HASH
Definition: snap.h:384
@ SNAP_STATUS_IDLE
Definition: snap.h:381
@ SNAP_HDB2_DAB_2BYTE_DEST_ADDRESS
Definition: snap.h:282
@ SNAP_HDB2_DAB_3BYTE_DEST_ADDRESS
Definition: snap.h:283
@ SNAP_HDB2_DAB_NO_DEST_ADDRESS
Definition: snap.h:280
@ SNAP_HDB2_DAB_1BYTE_DEST_ADDRESS
Definition: snap.h:281
@ SNAP_HDB1_EDM_USER_SPECIFIED
Definition: snap.h:349
@ SNAP_HDB1_EDM_8BIT_CHECKSUM
Definition: snap.h:344
@ SNAP_HDB1_EDM_3_RETRANSMISSION
Definition: snap.h:343
@ SNAP_HDB1_EDM_32BIT_CRC
Definition: snap.h:347
@ SNAP_HDB1_EDM_NO_ERROR_DETECTION
Definition: snap.h:342
@ SNAP_HDB1_EDM_16BIT_CRC
Definition: snap.h:346
@ SNAP_HDB1_EDM_8BIT_CRC
Definition: snap.h:345
@ SNAP_HDB1_EDM_FEC
Definition: snap.h:348
@ SNAP_FIELD_DATA
Definition: snap.h:271
@ SNAP_FIELD_SOURCE_ADDRESS
Definition: snap.h:269
@ SNAP_FIELD_HEADER
Definition: snap.h:267
@ SNAP_FIELD_HASH
Definition: snap.h:272
@ SNAP_FIELD_PROTOCOL_FLAGS
Definition: snap.h:270
@ SNAP_FIELD_DEST_ADDRESS
Definition: snap.h:268
@ SNAP_HDB2_PFB_1BYTE_PROTOCOL_FLAGS
Definition: snap.h:303
@ SNAP_HDB2_PFB_NO_PROTOCOL_FLAGS
Definition: snap.h:302
@ SNAP_HDB2_PFB_2BYTE_PROTOCOL_FLAGS
Definition: snap.h:304
@ SNAP_HDB2_PFB_3BYTE_PROTOCOL_FLAGS
Definition: snap.h:305
@ SNAP_HDB1_CMD_MODE_DISABLED
Definition: snap.h:332
@ SNAP_HDB1_CMD_MODE_ENABLED
Definition: snap.h:333
@ SNAP_HDB2_ACK_RESPONSE_ACK
Definition: snap.h:316
@ SNAP_HDB2_ACK_RESPONSE_NACK
Definition: snap.h:317
@ SNAP_HDB2_ACK_NOT_REQUESTED
Definition: snap.h:314
@ SNAP_HDB2_ACK_REQUESTED
Definition: snap.h:315
@ SNAP_HDB2_SAB_NO_SOURCE_ADDRESS
Definition: snap.h:291
@ SNAP_HDB2_SAB_2BYTE_SOURCE_ADDRESS
Definition: snap.h:293
@ SNAP_HDB2_SAB_1BYTE_SOURCE_ADDRESS
Definition: snap.h:292
@ SNAP_HDB2_SAB_3BYTE_SOURCE_ADDRESS
Definition: snap.h:294
@ SNAP_HDB1_NDB_2BYTE_DATA
Definition: snap.h:360
@ SNAP_HDB1_NDB_16BYTE_DATA
Definition: snap.h:367
@ SNAP_HDB1_NDB_3BYTE_DATA
Definition: snap.h:361
@ SNAP_HDB1_NDB_8BYTE_DATA
Definition: snap.h:366
@ SNAP_HDB1_NDB_5BYTE_DATA
Definition: snap.h:363
@ SNAP_HDB1_NDB_7BYTE_DATA
Definition: snap.h:365
@ SNAP_HDB1_NDB_6BYTE_DATA
Definition: snap.h:364
@ SNAP_HDB1_NDB_512BYTE_DATA
Definition: snap.h:372
@ SNAP_HDB1_NDB_1BYTE_DATA
Definition: snap.h:359
@ SNAP_HDB1_NDB_256BYTE_DATA
Definition: snap.h:371
@ SNAP_HDB1_NDB_USER_SPECIFIED
Definition: snap.h:373
@ SNAP_HDB1_NDB_128BYTE_DATA
Definition: snap.h:370
@ SNAP_HDB1_NDB_NO_DATA
Definition: snap.h:358
@ SNAP_HDB1_NDB_64BYTE_DATA
Definition: snap.h:369
@ SNAP_HDB1_NDB_4BYTE_DATA
Definition: snap.h:362
@ SNAP_HDB1_NDB_32BYTE_DATA
Definition: snap.h:368
Structure that stores every data necessary to build a new frame (i.e. every field value and size,...
Definition: snap.h:408
uint16_t dataSize
Number of bytes in the data array.
Definition: snap.h:414
bool paddingAfter
Position of the padding bytes in the payload (if there are any). true = padding after data,...
Definition: snap.h:415
snap_header_t header
Header bytes.
Definition: snap.h:413
uint32_t sourceAddress
Source address (up to 0xFFFFFF).
Definition: snap.h:411
uint32_t protocolFlags
Protocol specific flags (up to 0xFFFFFF).
Definition: snap.h:412
uint32_t destAddress
Destination address (up to 0xFFFFFF).
Definition: snap.h:410
uint8_t * data
Pointer to the array that holds the frame data/payload.
Definition: snap.h:409
This is the main structure of the library, used in frame decoding, encapsulation, and decapsulation.
Definition: snap.h:422
uint16_t maxSize
Maximum number of bytes that can be stored in the buffer.
Definition: snap.h:424
uint16_t size
Current size of the frame (it may be incomplete).
Definition: snap.h:425
int8_t status
Status of the frame, used primarily in the decoding process. It can assume any value from snap_status...
Definition: snap.h:426
uint8_t * buffer
Pointer to the array that stores all the bytes of the frame.
Definition: snap.h:423
Bit field that stores every field of the frame header. It defines the format of the frame.
Definition: snap.h:392
unsigned int sab
SAB (Source Address Bytes). It can assume any value from snap_hdb2_sab_t.
Definition: snap.h:395
unsigned int ndb
NDB (Number of Data Bytes). It can assume any value from snap_hdb1_ndb_t.
Definition: snap.h:401
unsigned int dab
DAB (Destination Address Bytes). It can assume any value from snap_hdb2_dab_t.
Definition: snap.h:394
unsigned int pfb
PFB (Protocol specific Flag Bytes). It can assume any value from snap_hdb2_pfb_t.
Definition: snap.h:396
unsigned int edm
EDM (Error Detection Method). It can assume any value from snap_hdb1_edm_t.
Definition: snap.h:400
unsigned int ack
ACK (ACK/NACK bits). It can assume any value from snap_hdb2_ack_t.
Definition: snap.h:397
unsigned int cmd
CMD (Command mode bit). It can assume any value from snap_hdb1_cmd_t.
Definition: snap.h:399