<commit_before>/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012 Intel Corporation. All rights reserved.
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <time.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

#include "hciattach.h"

#ifdef INTEL_DEBUG
#define DBGPRINT(fmt, args...)	printf("DBG: " fmt "\n", ## args)
#define PRINT_PACKET(buf, len, msg)	{	\
	int i;					\
	printf("%s\n", msg);			\
	for (i = 0; i < len; i++)		\
		printf("%02X ", buf[i]);	\
	printf("\n");				\
	}
#else
#define DBGPRINT(fmt, args...)
#define PRINT_PACKET(buf, len, msg)
#endif

#define PATCH_SEQ_EXT           ".bseq"
#define PATCH_FILE_PATH         "/lib/firmware/intel/"
#define PATCH_MAX_LEN           260
#define PATCH_TYPE_CMD          1
#define PATCH_TYPE_EVT          2

#define INTEL_VER_PARAM_LEN     9
#define INTEL_MFG_PARAM_LEN     2

/**
 * A data structure for a patch entry.
 */
struct patch_entry {
	int type;
	int len;
	unsigned char data[PATCH_MAX_LEN];
};

/**
 * A structure for patch context
 */
struct patch_ctx {
	int dev;
	int fd;
	int patch_error;
	int reset_enable_patch;
};

/**
 * Send HCI command to the controller
 */
static int intel_write_cmd(int dev, unsigned char *buf, int len)
{
	int ret;

	PRINT_PACKET(buf, len, "<----- SEND CMD: ");

	ret = write(dev, buf, len);
	if (ret < 0)
		return -errno;

	if (ret != len)
		return -1;

	return ret;
}

/**
 * Read the event from the controller
 */
static int intel_read_evt(int dev, unsigned char *buf, int len)
{
	int ret;

	ret = read_hci_event(dev, buf, len);
	if (ret < 0)
		return -1;

	PRINT_PACKET(buf, ret, "-----> READ EVT: ");

	return ret;
}

/**
 * Validate HCI events
 */
static int validate_events(struct patch_entry *event,
		struct patch_entry *entry)
{
	if (event == NULL || entry == NULL) {
		DBGPRINT("invalid patch entry parameters");
		return -1;
	}

	if (event->len != entry->len) {
		DBGPRINT("lengths are mismatched:[%d|%d]",
				event->len, entry->len);
		return -1;
	}

	if (memcmp(event->data, entry->data, event->len)) {
		DBGPRINT("data is mismatched");
		return -1;
	}

	return 0;
}

/**
 * Read the next patch entry one line at a time
 */
static int get_next_patch_entry(int fd, struct patch_entry *entry)
{
	int len, size;
	char rb;

	if (read(fd, &rb, 1) <= 0)
		return 0;

	entry->type = rb;
	len = 0;

	switch (entry->type) {
	case PATCH_TYPE_CMD:
		entry->data[0] = HCI_COMMAND_PKT;

		if (read(fd, &entry->data[1], 3) < 0)
			return -1;

		size = (int)entry->data[3];

		if (read(fd, &entry->data[4], size) < 0)
			return -1;

		entry->len = HCI_TYPE_LEN + HCI_COMMAND_HDR_SIZE + size;

		break;

	case PATCH_TYPE_EVT:
		entry->data[0] = HCI_EVENT_PKT;

		if (read(fd, &entry->data[len], 2) < 0)
			return -1;

		size = (int)entry->data[2];

		if (read(fd, &entry->data[3], size) < 0)
			return -1;

		entry->len = HCI_TYPE_LEN + HCI_EVENT_HDR_SIZE + size;

		break;

	default:
		fprintf(stderr, "invalid patch entry(%d)\n", entry->type);
		return -1;
	}

	return len;
}

/**
 * Download the patch set to the controller and verify the event
 */
static int intel_download_patch(struct patch_ctx *ctx)
{
	int ret;
	struct patch_entry entry;
	struct patch_entry event;

	DBGPRINT("start patch downloading");

	do {
		ret = get_next_patch_entry(ctx->fd, &entry);<commit_msg>hciattach: fix return length after reading the patch file<commit_after>/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012 Intel Corporation. All rights reserved.
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <time.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

#include "hciattach.h"

#ifdef INTEL_DEBUG
#define DBGPRINT(fmt, args...)	printf("DBG: " fmt "\n", ## args)
#define PRINT_PACKET(buf, len, msg)	{	\
	int i;					\
	printf("%s\n", msg);			\
	for (i = 0; i < len; i++)		\
		printf("%02X ", buf[i]);	\
	printf("\n");				\
	}
#else
#define DBGPRINT(fmt, args...)
#define PRINT_PACKET(buf, len, msg)
#endif

#define PATCH_SEQ_EXT           ".bseq"
#define PATCH_FILE_PATH         "/lib/firmware/intel/"
#define PATCH_MAX_LEN           260
#define PATCH_TYPE_CMD          1
#define PATCH_TYPE_EVT          2

#define INTEL_VER_PARAM_LEN     9
#define INTEL_MFG_PARAM_LEN     2

/**
 * A data structure for a patch entry.
 */
struct patch_entry {
	int type;
	int len;
	unsigned char data[PATCH_MAX_LEN];
};

/**
 * A structure for patch context
 */
struct patch_ctx {
	int dev;
	int fd;
	int patch_error;
	int reset_enable_patch;
};

/**
 * Send HCI command to the controller
 */
static int intel_write_cmd(int dev, unsigned char *buf, int len)
{
	int ret;

	PRINT_PACKET(buf, len, "<----- SEND CMD: ");

	ret = write(dev, buf, len);
	if (ret < 0)
		return -errno;

	if (ret != len)
		return -1;

	return ret;
}

/**
 * Read the event from the controller
 */
static int intel_read_evt(int dev, unsigned char *buf, int len)
{
	int ret;

	ret = read_hci_event(dev, buf, len);
	if (ret < 0)
		return -1;

	PRINT_PACKET(buf, ret, "-----> READ EVT: ");

	return ret;
}

/**
 * Validate HCI events
 */
static int validate_events(struct patch_entry *event,
		struct patch_entry *entry)
{
	if (event == NULL || entry == NULL) {
		DBGPRINT("invalid patch entry parameters");
		return -1;
	}

	if (event->len != entry->len) {
		DBGPRINT("lengths are mismatched:[%d|%d]",
				event->len, entry->len);
		return -1;
	}

	if (memcmp(event->data, entry->data, event->len)) {
		DBGPRINT("data is mismatched");
		return -1;
	}

	return 0;
}

/**
 * Read the next patch entry one line at a time
 */
static int get_next_patch_entry(int fd, struct patch_entry *entry)
{
	int size;
	char rb;

	if (read(fd, &rb, 1) <= 0)
		return 0;

	entry->type = rb;

	switch (entry->type) {
	case PATCH_TYPE_CMD:
		entry->data[0] = HCI_COMMAND_PKT;

		if (read(fd, &entry->data[1], 3) < 0)
			return -1;

		size = (int)entry->data[3];

		if (read(fd, &entry->data[4], size) < 0)
			return -1;

		entry->len = HCI_TYPE_LEN + HCI_COMMAND_HDR_SIZE + size;

		break;

	case PATCH_TYPE_EVT:
		entry->data[0] = HCI_EVENT_PKT;

		if (read(fd, &entry->data[1], 2) < 0)
			return -1;

		size = (int)entry->data[2];

		if (read(fd, &entry->data[3], size) < 0)
			return -1;

		entry->len = HCI_TYPE_LEN + HCI_EVENT_HDR_SIZE + size;

		break;

	default:
		fprintf(stderr, "invalid patch entry(%d)\n", entry->type);
		return -1;
	}

	return entry->len;
}

/**
 * Download the patch set to the controller and verify the event
 */
static int intel_download_patch(struct patch_ctx *ctx)
{
	int ret;
	struct patch_entry entry;
	struct patch_entry event;

	DBGPRINT("start patch downloading");

	do {
		ret = get_next_patch_entry(ctx->fd, &entry);
{'fraction_non_alphanumeric': 0.136938202247191, 'fraction_numerical': 0.013108614232209739, 'mean_word_length': 3.37980522808816, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 74, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2938080', 'n_tokens_mistral': 3294, 'n_tokens_neox': 3097, 'n_words': 972}