/*********************************************************************************
|
* Copyright: (C) 2020 LingYun IoT System Studio
|
* All rights reserved.
|
*
|
* Filename: tlv_pack.h
|
* Description: This head file is for TLV packet
|
*
|
* Version: 1.0.0(2020年04月14日)
|
* Author: Guo Wenxue <guowenxue@gmail.com>
|
* ChangeLog: 1, Release initial version on "2020年04月14日 00时52分56秒"
|
*
|
********************************************************************************/
|
|
#include <stdio.h>
|
#include <string.h>
|
|
#include "tlv_pack.h"
|
#include "crc-itu-t.h"
|
|
|
int packtlv_ack(char *buf, int size, int ack)
|
{
|
unsigned short crc16 = 0;
|
int pack_len = 0;
|
int ofset = 0; /* index position for the buf */
|
|
if(!buf || size<TLV_MIN_SIZE )
|
{
|
printf("Invalid input arguments\n");
|
return 0;
|
}
|
|
/*+-------------------------+
|
*| 1.fill packet Header |
|
*+-------------------------+*/
|
|
buf[ofset] = PACK_HEADER;
|
ofset += 1;
|
|
/*+-------------------------+
|
*| 2.fill packet Tag |
|
*+-------------------------+*/
|
|
buf[ofset] = TAG_ACK;
|
ofset += 1;
|
|
/*+-------------------------+
|
*| 3.fill packet Length |
|
*+-------------------------+*/
|
|
/* ACK message only get 1B payload data */
|
pack_len = TLV_FIXED_SIZE + 1;
|
buf[ofset] = pack_len;
|
ofset += 1;
|
|
/*+-------------------------+
|
*| 4.fill packet Value |
|
*+-------------------------+*/
|
|
if( ack )
|
buf[ofset++] = 1; /* 1 for ACK */
|
else
|
buf[ofset++] = 0; /* 0 for NAK */
|
|
/*+-------------------------+
|
*| 5.fill packet CRC |
|
*+-------------------------+*/
|
|
/* Calc CRC16 checksum value from Packet Head(buf[0]) ~ Value(buf[ofset]) */
|
crc16 = crc_itu_t(MAGIC_CRC, buf, ofset);
|
|
/* Append the 2 Bytes CRC16 checksum value into the last two bytes in packet buffer */
|
ushort_to_bytes(&buf[ofset], crc16);
|
ofset += 2;
|
|
/* ofset value is the TLV packet length */
|
return ofset;
|
}
|
|
|
int packtlv_sn(char *buf, int size, char *sn)
|
{
|
unsigned short crc16 = 0;
|
int payload_len = 0;
|
int pack_len = 0;
|
int ofset = 0; /* index position for the buf */
|
|
if(!buf || size<TLV_MIN_SIZE )
|
{
|
printf("Invalid input arguments\n");
|
return 0;
|
}
|
|
/*+-------------------------+
|
*| 1.fill packet Header |
|
*+-------------------------+*/
|
buf[ofset] = PACK_HEADER;
|
ofset += 1;
|
|
/*+-------------------------+
|
*| 2.fill packet Tag |
|
*+-------------------------+*/
|
buf[ofset] = TAG_SN;
|
ofset += 1;
|
|
/*+-------------------------+
|
*| 3.fill packet Length |
|
*+-------------------------+*/
|
|
/* $sn too long maybe result buffer overflow, so we need check the buffer
|
* is large enuf or not. If not enuf we will truncate $sn string
|
*/
|
if( strlen(sn) <= size-TLV_FIXED_SIZE )
|
payload_len = strlen(sn);
|
else
|
payload_len = size-TLV_FIXED_SIZE;
|
|
/* TLV packet length is SN length+5Byte () */
|
pack_len = payload_len + TLV_FIXED_SIZE;
|
|
buf[ofset] = pack_len;
|
ofset += 1;
|
|
/*+-------------------------+
|
*| 4.fill packet Value |
|
*+-------------------------+*/
|
memcpy(&buf[ofset], sn, payload_len);
|
ofset += payload_len;
|
|
/*+-------------------------+
|
*| 5.fill packet CRC |
|
*+-------------------------+*/
|
|
/* Calc CRC16 checksum value from Packet Head(buf[0]) ~ Value(buf[ofset]) */
|
crc16 = crc_itu_t(MAGIC_CRC, buf, ofset);
|
|
/* Append the 2 Bytes CRC16 checksum value into the last two bytes in packet buffer */
|
ushort_to_bytes(&buf[ofset], crc16);
|
ofset += 2;
|
|
/* ofset value is the TLV packet length */
|
return ofset;
|
}
|
|
|
int packtlv_temp(char *buf, int size, uint16_t temp)
|
{
|
unsigned short crc16 = 0;
|
int pack_len = 0;
|
int ofset = 0; /* index position for the buf */
|
|
if(!buf || size<TLV_FIXED_SIZE+2 )
|
{
|
printf("Invalid input arguments\n");
|
return 0;
|
}
|
|
/*+-------------------------+
|
*| 1.fill packet Header |
|
*+-------------------------+*/
|
|
buf[ofset] = PACK_HEADER;
|
ofset += 1;
|
|
/*+-------------------------+
|
*| 2.fill packet Tag |
|
*+-------------------------+*/
|
|
buf[ofset] = TAG_TEMP;
|
ofset += 1;
|
|
/*+-------------------------+
|
*| 3.fill packet Length |
|
*+-------------------------+*/
|
|
/* termperature message get 2B payload data */
|
pack_len = TLV_FIXED_SIZE + 2;
|
buf[ofset] = pack_len;
|
ofset += 1;
|
|
/*+-------------------------+
|
*| 4.fill packet Value |
|
*+-------------------------+*/
|
|
/* temperature get 2 bytes, byte[0]:integer part, byte[1]:fractional part */
|
memcpy(&buf[ofset], &temp, 2);
|
ofset += 2;
|
|
/*+-------------------------+
|
*| 5.fill packet CRC |
|
*+-------------------------+*/
|
|
/* Calc CRC16 checksum value from Packet Head(buf[0]) ~ Value(buf[ofset]) */
|
crc16 = crc_itu_t(MAGIC_CRC, buf, ofset);
|
|
/* Append the 2 Bytes CRC16 checksum value into the last two bytes in packet buffer */
|
ushort_to_bytes(&buf[ofset], crc16);
|
ofset += 2;
|
|
/* ofset value is the TLV packet length */
|
return ofset;
|
}
|
|
int packtlv_time(char *buf, int size, struct tm *tm)
|
{
|
unsigned short crc16 = 0;
|
int pack_len = 0;
|
int ofset = 0; /* index position for the buf */
|
|
if(!buf || size<TLV_FIXED_SIZE+6 )
|
{
|
printf("Invalid input arguments\n");
|
return 0;
|
}
|
|
/*+-------------------------+
|
*| 1.fill packet Header |
|
*+-------------------------+*/
|
|
buf[ofset] = PACK_HEADER;
|
ofset += 1;
|
|
/*+-------------------------+
|
*| 2.fill packet Tag |
|
*+-------------------------+*/
|
|
buf[ofset] = TAG_TIME;
|
ofset += 1;
|
|
/*+-------------------------+
|
*| 3.fill packet Length |
|
*+-------------------------+*/
|
|
/* date time message get 6B payload data */
|
pack_len = TLV_FIXED_SIZE + 6;
|
buf[ofset] = pack_len;
|
ofset += 1;
|
|
/*+-------------------------+
|
*| 4.fill packet Value |
|
*+-------------------------+*/
|
|
buf[ofset++] = tm->tm_year-100; /* tm_year is since 1900, we change it it to 2000 */
|
buf[ofset++] = tm->tm_mon+1; /* tm_mon is from 0~11 */
|
buf[ofset++] = tm->tm_mday;
|
buf[ofset++] = tm->tm_hour;
|
buf[ofset++] = tm->tm_min;
|
buf[ofset++] = tm->tm_sec;
|
|
/*+-------------------------+
|
*| 5.fill packet CRC |
|
*+-------------------------+*/
|
|
/* Calc CRC16 checksum value from Packet Head(buf[0]) ~ Value(buf[ofset]) */
|
crc16 = crc_itu_t(MAGIC_CRC, buf, ofset);
|
|
/* Append the 2 Bytes CRC16 checksum value into the last two bytes in packet buffer */
|
ushort_to_bytes(&buf[ofset], crc16);
|
ofset += 2;
|
|
/* ofset value is the TLV packet length */
|
return ofset;
|
}
|
|
|
|
/*+------------------------------+
|
*| dump_buf() implement code |
|
*+------------------------------+*/
|
|
#define LINELEN 81
|
#define CHARS_PER_LINE 16
|
|
static char *print_char =
|
" "
|
" "
|
" !\"#$%&'()*+,-./"
|
"0123456789:;<=>?"
|
"@ABCDEFGHIJKLMNO"
|
"PQRSTUVWXYZ[\\]^_"
|
"`abcdefghijklmno"
|
"pqrstuvwxyz{|}~ "
|
" "
|
" "
|
" ???????????????"
|
"????????????????"
|
"????????????????"
|
"????????????????"
|
"????????????????"
|
"????????????????";
|
|
/* print every byte in the buffer as HEX and corresponding charactor, which is not printable charactor will be instead as '?' */
|
void dump_buf(char *data, int len)
|
{
|
int rc;
|
int idx;
|
char prn[LINELEN];
|
char lit[CHARS_PER_LINE + 1];
|
char hc[4];
|
short line_done = 1;
|
|
rc = len;
|
idx = 0;
|
lit[CHARS_PER_LINE] = '\0';
|
|
while (rc > 0)
|
{
|
if (line_done)
|
snprintf(prn, LINELEN, "%08X: ", idx);
|
do
|
{
|
unsigned char c = data[idx];
|
snprintf(hc, 4, "%02X ", c);
|
strncat(prn, hc, 4);
|
lit[idx % CHARS_PER_LINE] = print_char[c];
|
++idx;
|
} while (--rc > 0 && (idx % CHARS_PER_LINE != 0));
|
|
line_done = (idx % CHARS_PER_LINE) == 0;
|
|
if (line_done)
|
printf("%s %s\n", prn, lit);
|
else if (rc == 0)
|
strncat(prn, " ", LINELEN);
|
}
|
|
if (!line_done)
|
{
|
lit[(idx % CHARS_PER_LINE)] = '\0';
|
|
while ((++idx % CHARS_PER_LINE) != 0)
|
strncat(prn, " ", LINELEN);
|
|
printf("%s %s\n", prn, lit);
|
|
}
|
}
|