Blame tools/mesh/util.c

Packit 34410b
/*
Packit 34410b
 *
Packit 34410b
 *  BlueZ - Bluetooth protocol stack for Linux
Packit 34410b
 *
Packit 34410b
 *  Copyright (C) 2017  Intel Corporation. All rights reserved.
Packit 34410b
 *
Packit 34410b
 *
Packit 34410b
 *  This library is free software; you can redistribute it and/or
Packit 34410b
 *  modify it under the terms of the GNU Lesser General Public
Packit 34410b
 *  License as published by the Free Software Foundation; either
Packit 34410b
 *  version 2.1 of the License, or (at your option) any later version.
Packit 34410b
 *
Packit 34410b
 *  This library is distributed in the hope that it will be useful,
Packit 34410b
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 34410b
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 34410b
 *  Lesser General Public License for more details.
Packit 34410b
 *
Packit 34410b
 *  You should have received a copy of the GNU Lesser General Public
Packit 34410b
 *  License along with this library; if not, write to the Free Software
Packit 34410b
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
Packit 34410b
 *
Packit 34410b
 */
Packit 34410b
Packit 34410b
#ifdef HAVE_CONFIG_H
Packit 34410b
#include <config.h>
Packit 34410b
#endif
Packit 34410b
Packit 34410b
#include <stdio.h>
Packit 34410b
#include <stdbool.h>
Packit 34410b
#include <inttypes.h>
Packit 34410b
Packit 34410b
#include <glib.h>
Packit 34410b
Packit 34410b
#include "src/shared/shell.h"
Packit 34410b
#include "src/shared/util.h"
Packit 34410b
#include "tools/mesh/mesh-net.h"
Packit 34410b
#include "tools/mesh/node.h"
Packit 34410b
#include "tools/mesh/util.h"
Packit 34410b
Packit 34410b
void set_menu_prompt(const char *name, const char *id)
Packit 34410b
{
Packit 34410b
	char *prompt;
Packit 34410b
Packit 34410b
	prompt = g_strdup_printf(COLOR_BLUE "[%s%s%s]" COLOR_OFF "# ", name,
Packit 34410b
					id ? ": Target = " : "", id ? id : "");
Packit 34410b
	bt_shell_set_prompt(prompt);
Packit 34410b
	g_free(prompt);
Packit 34410b
}
Packit 34410b
Packit 34410b
void print_byte_array(const char *prefix, const void *ptr, int len)
Packit 34410b
{
Packit 34410b
	const uint8_t *data = ptr;
Packit 34410b
	char *line, *bytes;
Packit 34410b
	int i;
Packit 34410b
Packit 34410b
	line = g_malloc(strlen(prefix) + (16 * 3) + 2);
Packit 34410b
	sprintf(line, "%s ", prefix);
Packit 34410b
	bytes = line + strlen(prefix) + 1;
Packit 34410b
Packit 34410b
	for (i = 0; i < len; ++i) {
Packit 34410b
		sprintf(bytes, "%2.2x ", data[i]);
Packit 34410b
		if ((i + 1) % 16) {
Packit 34410b
			bytes += 3;
Packit 34410b
		} else {
Packit 34410b
			bt_shell_printf("\r%s\n", line);
Packit 34410b
			bytes = line + strlen(prefix) + 1;
Packit 34410b
		}
Packit 34410b
	}
Packit 34410b
Packit 34410b
	if (i % 16)
Packit 34410b
		bt_shell_printf("\r%s\n", line);
Packit 34410b
Packit 34410b
	g_free(line);
Packit 34410b
}
Packit 34410b
Packit 34410b
bool str2hex(const char *str, uint16_t in_len, uint8_t *out,
Packit 34410b
		uint16_t out_len)
Packit 34410b
{
Packit 34410b
	uint16_t i;
Packit 34410b
Packit 34410b
	if (in_len < out_len * 2)
Packit 34410b
		return false;
Packit 34410b
Packit 34410b
	for (i = 0; i < out_len; i++) {
Packit 34410b
		if (sscanf(&str[i * 2], "%02hhx", &out[i]) != 1)
Packit 34410b
			return false;
Packit 34410b
	}
Packit 34410b
Packit 34410b
	return true;
Packit 34410b
}
Packit 34410b
Packit 34410b
size_t hex2str(uint8_t *in, size_t in_len, char *out,
Packit 34410b
		size_t out_len)
Packit 34410b
{
Packit 34410b
	static const char hexdigits[] = "0123456789abcdef";
Packit 34410b
	size_t i;
Packit 34410b
Packit 34410b
	if(in_len * 2 > out_len - 1)
Packit 34410b
		return 0;
Packit 34410b
Packit 34410b
	for (i = 0; i < in_len; i++) {
Packit 34410b
		out[i * 2] = hexdigits[in[i] >> 4];
Packit 34410b
		out[i * 2 + 1] = hexdigits[in[i] & 0xf];
Packit 34410b
	}
Packit 34410b
Packit 34410b
	out[in_len * 2] = '\0';
Packit 34410b
	return i;
Packit 34410b
}
Packit 34410b
Packit 34410b
uint16_t mesh_opcode_set(uint32_t opcode, uint8_t *buf)
Packit 34410b
{
Packit 34410b
	if (opcode <= 0x7e) {
Packit 34410b
		buf[0] = opcode;
Packit 34410b
		return 1;
Packit 34410b
	} else if (opcode >= 0x8000 && opcode <= 0xbfff) {
Packit 34410b
		put_be16(opcode, buf);
Packit 34410b
		return 2;
Packit 34410b
	} else if (opcode >= 0xc00000 && opcode <= 0xffffff) {
Packit 34410b
		buf[0] = (opcode >> 16) & 0xff;
Packit 34410b
		put_be16(opcode, buf + 1);
Packit 34410b
		return 3;
Packit 34410b
	} else {
Packit 34410b
		bt_shell_printf("Illegal Opcode %x", opcode);
Packit 34410b
		return 0;
Packit 34410b
	}
Packit 34410b
}
Packit 34410b
Packit 34410b
bool mesh_opcode_get(const uint8_t *buf, uint16_t sz, uint32_t *opcode, int *n)
Packit 34410b
{
Packit 34410b
	if (!n || !opcode || sz < 1) return false;
Packit 34410b
Packit 34410b
	switch (buf[0] & 0xc0) {
Packit 34410b
	case 0x00:
Packit 34410b
	case 0x40:
Packit 34410b
		/* RFU */
Packit 34410b
		if (buf[0] == 0x7f)
Packit 34410b
			return false;
Packit 34410b
Packit 34410b
		*n = 1;
Packit 34410b
		*opcode = buf[0];
Packit 34410b
		break;
Packit 34410b
Packit 34410b
	case 0x80:
Packit 34410b
		if (sz < 2)
Packit 34410b
			return false;
Packit 34410b
Packit 34410b
		*n = 2;
Packit 34410b
		*opcode = get_be16(buf);
Packit 34410b
		break;
Packit 34410b
Packit 34410b
	case 0xc0:
Packit 34410b
		if (sz < 3)
Packit 34410b
			return false;
Packit 34410b
Packit 34410b
		*n = 3;
Packit 34410b
		*opcode = get_be16(buf + 1);
Packit 34410b
		*opcode |= buf[0] << 16;
Packit 34410b
		break;
Packit 34410b
Packit 34410b
	default:
Packit 34410b
		bt_shell_printf("Bad Packet:\n");
Packit 34410b
		print_byte_array("\t", (void *) buf, sz);
Packit 34410b
		return false;
Packit 34410b
	}
Packit 34410b
Packit 34410b
	return true;
Packit 34410b
}
Packit 34410b
Packit 34410b
const char *mesh_status_str(uint8_t status)
Packit 34410b
{
Packit 34410b
	switch (status) {
Packit 34410b
	case MESH_STATUS_SUCCESS: return "Success";
Packit 34410b
	case MESH_STATUS_INVALID_ADDRESS: return "Invalid Address";
Packit 34410b
	case MESH_STATUS_INVALID_MODEL: return "Invalid Model";
Packit 34410b
	case MESH_STATUS_INVALID_APPKEY: return "Invalid AppKey";
Packit 34410b
	case MESH_STATUS_INVALID_NETKEY: return "Invalid NetKey";
Packit 34410b
	case MESH_STATUS_INSUFF_RESOURCES: return "Insufficient Resources";
Packit 34410b
	case MESH_STATUS_IDX_ALREADY_STORED: return "Key Idx Already Stored";
Packit 34410b
	case MESH_STATUS_INVALID_PUB_PARAM: return "Invalid Publish Parameters";
Packit 34410b
	case MESH_STATUS_NOT_SUB_MOD: return "Not a Subscribe Model";
Packit 34410b
	case MESH_STATUS_STORAGE_FAIL: return "Storage Failure";
Packit 34410b
	case MESH_STATUS_FEAT_NOT_SUP: return "Feature Not Supported";
Packit 34410b
	case MESH_STATUS_CANNOT_UPDATE: return "Cannot Update";
Packit 34410b
	case MESH_STATUS_CANNOT_REMOVE: return "Cannot Remove";
Packit 34410b
	case MESH_STATUS_CANNOT_BIND: return "Cannot bind";
Packit 34410b
	case MESH_STATUS_UNABLE_CHANGE_STATE: return "Unable to change state";
Packit 34410b
	case MESH_STATUS_CANNOT_SET: return "Cannot set";
Packit 34410b
	case MESH_STATUS_UNSPECIFIED_ERROR: return "Unspecified error";
Packit 34410b
	case MESH_STATUS_INVALID_BINDING: return "Invalid Binding";
Packit 34410b
Packit 34410b
	default: return "Unknown";
Packit 34410b
	}
Packit 34410b
}
Packit 34410b
Packit 34410b
void print_model_pub(uint16_t ele_addr, uint32_t mod_id,
Packit 34410b
						struct mesh_publication *pub)
Packit 34410b
{
Packit 34410b
	bt_shell_printf("\tElement: %4.4x\n", ele_addr);
Packit 34410b
	bt_shell_printf("\tPub Addr: %4.4x", pub->u.addr16);
Packit 34410b
	if (mod_id > 0xffff0000)
Packit 34410b
		bt_shell_printf("\tModel: %8.8x \n", mod_id);
Packit 34410b
	else
Packit 34410b
		bt_shell_printf("\tModel: %4.4x \n",
Packit 34410b
				(uint16_t) (mod_id & 0xffff));
Packit 34410b
	bt_shell_printf("\tApp Key Idx: %4.4x", pub->app_idx);
Packit 34410b
	bt_shell_printf("\tTTL: %2.2x", pub->ttl);
Packit 34410b
}
Packit 34410b
Packit 34410b
void swap_u256_bytes(uint8_t *u256)
Packit 34410b
{
Packit 34410b
	int i;
Packit 34410b
Packit 34410b
	/* End-to-End byte reflection of 32 octet buffer */
Packit 34410b
	for (i = 0; i < 16; i++) {
Packit 34410b
		u256[i] ^= u256[31 - i];
Packit 34410b
		u256[31 - i] ^= u256[i];
Packit 34410b
		u256[i] ^= u256[31 - i];
Packit 34410b
	}
Packit 34410b
}