/*********************************************************************************
|
* Copyright: (C) 2019 LingYun IoT studio
|
* All rights reserved.
|
*
|
* Filename: tlv_sample.c
|
* Description: This file
|
*
|
* Version: 1.0.0(03/27/2019)
|
* Author: Guo Wenxue <guowenxue@gmail.com>
|
* ChangeLog: 1, Release initial version on "03/27/2019 09:20:25 PM"
|
*
|
********************************************************************************/
|
|
#include <stdio.h>
|
#include <string.h>
|
#include "crc-itu-t.h"
|
|
#define OFF 0
|
#define ON 1
|
|
#define BUFSIZE 128
|
|
/* TLV Packet format:
|
*
|
*+------------+---------+------------+-----------+-----------+
|
*| Header(1B) | Tag(1B) | Length(1B) | Value(1B) | CRC16(2B) |
|
*+------------+---------+------------+-----------+-----------+
|
*/
|
|
#define PACK_HEADER 0xFD
|
|
/* Tag definition */
|
enum
|
{
|
TAG_LOGON=1,
|
TAG_CAMERA,
|
TAG_LED,
|
};
|
|
/* TLV packet fixed segement size, 1B Head, 1B Tag, 1B length, 2B CRC16, total 5B. */
|
#define TLV_FIXED_SIZE 5
|
|
/* TLV packet Minimum size is fixed bytes + 1 byte data */
|
#define TLV_MIN_SIZE (TLV_FIXED_SIZE+1)
|
|
int packtlv_logon(char *buf, int size, char *pwd);
|
int packtlv_led(char *buf, int size, int cmd);
|
void dump_buf(char *data, int len);
|
|
int main(int argc, char **argv)
|
{
|
char buf[BUFSIZE];
|
int bytes;
|
|
bytes = packtlv_led(buf, sizeof(buf), ON);
|
|
/* print every byte in the buffer as HEX and corresponding charactor,
|
which is not printable charactor will be instead as '?' */
|
dump_buf(buf, bytes);
|
|
bytes = packtlv_logon(buf, sizeof(buf), "iot@yun");
|
|
dump_buf(buf, bytes);
|
|
return 0;
|
}
|
|
|
int packtlv_logon(char *buf, int size, char *pwd)
|
{
|
unsigned short crc16 = 0;
|
int pack_len = 0;
|
int data_len = 0;
|
int ofset = 0; /* index position for the buf */
|
|
if(!buf || !pwd || size<TLV_MIN_SIZE )
|
{
|
printf("Invalid input arguments\n");
|
return 0;
|
}
|
|
/* Packet head */
|
buf[ofset] = PACK_HEADER;
|
ofset += 1;
|
|
/* Tag */
|
buf[ofset] = TAG_LOGON;
|
ofset += 1;
|
|
/* $pwd too long maybe result buffer overflow, so we need check the buffer
|
* is large enuf or not. If buf size is not enuf we will truncate $pwd string */
|
if( strlen(pwd) <= size-TLV_FIXED_SIZE )
|
data_len = strlen(pwd);
|
else
|
data_len = size-TLV_FIXED_SIZE;
|
|
/* Length, this packet is passwd length+5Byte () */
|
pack_len = data_len + TLV_FIXED_SIZE;
|
|
buf[ofset] = pack_len;
|
ofset += 1;
|
|
memcpy(&buf[ofset], pwd, data_len);
|
ofset += data_len;
|
|
/* 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;
|
|
return ofset;
|
}
|
|
|
|
int packtlv_led(char *buf, int size, int cmd)
|
{
|
unsigned short crc16;
|
int pack_len = TLV_FIXED_SIZE+1; /* Only 1 byte data */
|
|
if(!buf || size<TLV_MIN_SIZE )
|
{
|
printf("Invalid input arguments\n");
|
return 0;
|
}
|
|
/* Packet head */
|
buf[0] = PACK_HEADER;
|
|
/* Tag */
|
buf[1] = TAG_LED;
|
|
/* Length, this packet total 6 bytes */
|
buf[2] = pack_len;
|
|
/* Value */
|
buf[3] = (OFF==cmd) ? 0x00 : 0x01;
|
|
/* Calc CRC16 checksum value from Packet Head(buf[0])~ Packet Value(buf[3]) */
|
crc16 = crc_itu_t(MAGIC_CRC, buf, 4);
|
|
/* Append the 2 Bytes CRC16 checksum value into the last two bytes in packet buffer */
|
ushort_to_bytes(&buf[4], crc16);
|
|
return pack_len;
|
}
|
|
|
/*+------------------------------+
|
*| 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);
|
|
}
|
}
|