<commit_before>/* HM-MOD-UART/HM-LGW-O-TW-W-EU driver
 *
 * Copyright (c) 2016 <NAME> <<EMAIL>>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <poll.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>

#include "hexdump.h"
#include "hmuartlgw.h"

#define HMUARTLGW_INIT_TIMEOUT	10000

#define HMUARTLGW_SETTLE_TIME	2

static int debug = 0;

enum hmuartlgw_state {
	HMUARTLGW_QUERY_APPSTATE,
	HMUARTLGW_ENTER_BOOTLOADER,
	HMUARTLGW_ENTER_BOOTLOADER_ACK,
	HMUARTLGW_BOOTLOADER,
	HMUARTLGW_ENTER_APPLICATION,
	HMUARTLGW_ENTER_APPLICATION_ACK,
	HMUARTLGW_APPLICATION,
};

struct recv_data {
	enum hmuartlgw_state state;
};


#define CRC16_POLY	0x8005

static uint16_t crc16(uint8_t* buf, int length)
{
	uint16_t crc = 0xd77f;
	int i;

	while (length--) {
		crc ^= *buf++ << 8;
		for (i = 0; i < 8; i++) {
			if (crc & 0x8000) {
				crc <<= 1;
				crc ^= CRC16_POLY;
			} else {
				crc <<= 1;
			}
		}
	}

	return crc;
}

static int hmuartlgw_init_parse(enum hmuartlgw_dst dst, uint8_t *buf, int buf_len, void *data)
{
	struct recv_data *rdata = data;

#if 0
	if (debug) {
		printf("Length: %d\n", buf_len);
		hexdump(buf, buf_len, "INIT > ");
	}
#endif

	if (dst != HMUARTLGW_OS)
		return 0;

	if ((buf_len == 10) && (buf[0] == 0x00) && !strncmp(((char*)buf)+1, "Co_CPU_BL", 9)) {
		rdata->state = HMUARTLGW_BOOTLOADER;
		return 1;
	}

	if ((buf_len == 11) && (buf[0] == 0x00) && !strncmp(((char*)buf)+1, "Co_CPU_App", 10)) {
		rdata->state = HMUARTLGW_APPLICATION;
		return 1;
	}

	switch(rdata->state) {
		case HMUARTLGW_QUERY_APPSTATE:
			if ((buf[0] == 0x04) && (buf[1] == 0x02)) {
				if (!strncmp(((char*)buf)+2, "Co_CPU_BL", 9)) {
					rdata->state = HMUARTLGW_BOOTLOADER;
				} else if (!strncmp(((char*)buf)+2, "Co_CPU_App", 10)) {
					rdata->state = HMUARTLGW_APPLICATION;
				}
			}
			break;
		case HMUARTLGW_ENTER_BOOTLOADER:
			if ((buf_len == 2) &&
			    (buf[0] == 0x04) &&
			    (buf[1] == 0x01)) {
				rdata->state = HMUARTLGW_ENTER_BOOTLOADER_ACK;
			}
			break;
		case HMUARTLGW_ENTER_BOOTLOADER_ACK:
			rdata->state = HMUARTLGW_ENTER_BOOTLOADER;
			break;
		case HMUARTLGW_ENTER_APPLICATION:
			if ((buf_len == 2) &&
			    (buf[0] == 0x04) &&
			    (buf[1] == 0x01)) {
				rdata->state = HMUARTLGW_ENTER_APPLICATION_ACK;
			}
			break;
		case HMUARTLGW_ENTER_APPLICATION_ACK:
			rdata->state = HMUARTLGW_ENTER_APPLICATION;
			break;
		default:
			return 0;
			break;
	}

        return 1;
}

struct hmuartlgw_dev *hmuart_init(char *device, hmuartlgw_cb_fn cb, void *data)
{
	struct hmuartlgw_dev *dev = NULL;
	struct termios oldtio, tio;

	dev = malloc(sizeof(struct hmuartlgw_dev));
	if (dev == NULL) {
		perror("malloc(struct hmuartlgw_dev)");
		return NULL;
	}

	memset(dev, 0, sizeof(struct hmuartlgw_dev));
<commit_msg>hmuartlgw: use defines, decrease settle time<commit_after>/* HM-MOD-UART/HM-LGW-O-TW-W-EU driver
 *
 * Copyright (c) 2016 <NAME> <<EMAIL>>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <poll.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>

#include "hexdump.h"
#include "hmuartlgw.h"

#define HMUARTLGW_INIT_TIMEOUT	10000

#define HMUARTLGW_SETTLE_TIME	1

static int debug = 0;

enum hmuartlgw_state {
	HMUARTLGW_QUERY_APPSTATE,
	HMUARTLGW_ENTER_BOOTLOADER,
	HMUARTLGW_ENTER_BOOTLOADER_ACK,
	HMUARTLGW_BOOTLOADER,
	HMUARTLGW_ENTER_APPLICATION,
	HMUARTLGW_ENTER_APPLICATION_ACK,
	HMUARTLGW_APPLICATION,
};

struct recv_data {
	enum hmuartlgw_state state;
};


#define CRC16_POLY	0x8005

static uint16_t crc16(uint8_t* buf, int length)
{
	uint16_t crc = 0xd77f;
	int i;

	while (length--) {
		crc ^= *buf++ << 8;
		for (i = 0; i < 8; i++) {
			if (crc & 0x8000) {
				crc <<= 1;
				crc ^= CRC16_POLY;
			} else {
				crc <<= 1;
			}
		}
	}

	return crc;
}

static int hmuartlgw_init_parse(enum hmuartlgw_dst dst, uint8_t *buf, int buf_len, void *data)
{
	struct recv_data *rdata = data;

#if 0
	if (debug) {
		printf("Length: %d\n", buf_len);
		hexdump(buf, buf_len, "INIT > ");
	}
#endif

	if (dst != HMUARTLGW_OS)
		return 0;

	if ((buf_len == 10) && (buf[0] == 0x00) && !strncmp(((char*)buf)+1, "Co_CPU_BL", 9)) {
		rdata->state = HMUARTLGW_BOOTLOADER;
		return 1;
	}

	if ((buf_len == 11) && (buf[0] == 0x00) && !strncmp(((char*)buf)+1, "Co_CPU_App", 10)) {
		rdata->state = HMUARTLGW_APPLICATION;
		return 1;
	}

	switch(rdata->state) {
		case HMUARTLGW_QUERY_APPSTATE:
			if ((buf[0] == HMUARTLGW_OS_ACK) && (buf[1] == 0x02)) {
				if (!strncmp(((char*)buf)+2, "Co_CPU_BL", 9)) {
					rdata->state = HMUARTLGW_BOOTLOADER;
				} else if (!strncmp(((char*)buf)+2, "Co_CPU_App", 10)) {
					rdata->state = HMUARTLGW_APPLICATION;
				}
			}
			break;
		case HMUARTLGW_ENTER_BOOTLOADER:
			if ((buf_len == 2) &&
			    (buf[0] == HMUARTLGW_OS_ACK) &&
			    (buf[1] == 0x01)) {
				rdata->state = HMUARTLGW_ENTER_BOOTLOADER_ACK;
			}
			break;
		case HMUARTLGW_ENTER_BOOTLOADER_ACK:
			rdata->state = HMUARTLGW_ENTER_BOOTLOADER;
			break;
		case HMUARTLGW_ENTER_APPLICATION:
			if ((buf_len == 2) &&
			    (buf[0] == HMUARTLGW_OS_ACK) &&
			    (buf[1] == 0x01)) {
				rdata->state = HMUARTLGW_ENTER_APPLICATION_ACK;
			}
			break;
		case HMUARTLGW_ENTER_APPLICATION_ACK:
			rdata->state = HMUARTLGW_ENTER_APPLICATION;
			break;
		default:
			return 0;
			break;
	}

        return 1;
}

struct hmuartlgw_dev *hmuart_init(char *device, hmuartlgw_cb_fn cb, void *data)
{
	struct hmuartlgw_dev *dev = NULL;
	struct termios oldtio, tio;

	dev = malloc(sizeof(struct hmuartlgw_dev));
	if (dev == NULL) {
		perror("malloc(struct hmuartlgw_dev)");
		return NULL;
	}

	memset(dev, 0, sizeof(struct hmuartlgw_dev));

{'fraction_non_alphanumeric': 0.12551568946118266, 'fraction_numerical': 0.02287785973246656, 'mean_word_length': 4.031446540880503, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2517218', 'n_tokens_mistral': 3608, 'n_tokens_neox': 3062, 'n_words': 817}