From 77cd612f15cb8b50229dbba5e8ec18c8a0bca6f5 Mon Sep 17 00:00:00 2001 From: "martin.holst@gmail.com" Date: Wed, 6 Nov 2013 18:34:10 +0000 Subject: [PATCH] Added a lua bit manipulation library, added Lua-api to iso 15693 crc-calculation --- client/Makefile | 2 +- client/README-bitlib | 71 +++++++++++++++++++ client/cmdscript.c | 4 +- client/pm3_bit_limits.h | 4 ++ client/pm3_bitlib.c | 152 ++++++++++++++++++++++++++++++++++++++++ client/pm3_bitlib.h | 7 ++ client/scripting.c | 12 +++- 7 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 client/README-bitlib create mode 100644 client/pm3_bit_limits.h create mode 100644 client/pm3_bitlib.c create mode 100644 client/pm3_bitlib.h diff --git a/client/Makefile b/client/Makefile index 382d10f4..521b036a 100644 --- a/client/Makefile +++ b/client/Makefile @@ -85,7 +85,7 @@ CMDSRCS = nonce2key/crapto1.c\ pm3_binlib.c\ scripting.c\ cmdscript.c\ - + pm3_bitlib.c\ COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o) diff --git a/client/README-bitlib b/client/README-bitlib new file mode 100644 index 00000000..76683a2f --- /dev/null +++ b/client/README-bitlib @@ -0,0 +1,71 @@ + bitlib + ------ + + by Reuben Thomas + http://luaforge.net/projects/bitlib + + +bitlib is a C library for Lua 5.1 that provides bitwise operations. It +is copyright Reuben Thomas 2000-2009, and is released under the MIT +license, like Lua (see http://www.lua.org/copyright.html; it's +basically the same as the BSD license). There is no warranty. + +Please report bugs and make suggestions to the email address above, or +use the LuaForge trackers. + +Thanks to John Passaniti for his bitwise operations library, some of +whose ideas I used, to Shmuel Zeigerman for the test suite, to +Thatcher Ulrich for portability fixes, and to Enrico Tassi, John +Stiles and Eduardo Ochs for bug reports. + + +Installation +------------ + +As normal: + + ./configure && make [&& make check] [&& make install] + +If you get warnings about integer constants being too large, don't +worry. They won't be used. + +The following options may be of interest if you have Lua installed on +non-default paths (as you are likely to on any system supporting more +than one version of Lua): + + --libdir=DIR Install shared library in this directory + --with-lua-prefix=DIR Lua files are in DIR + --with-lua-includes=DIR Lua include files are in DIR + --with-lua-libraries=DIR + Lua library files are in DIR, or "no" if not used + --with-lua-suffix=ARG Lua binary and library files are suffixed with ARG + +For example, on Debian or Ubuntu: + + ./configure --libdir=/usr/local/lib/lua/5.1 --with-lua-includes=/usr/include/lua5.1 --with-lua-suffix=5.1 --with-lua-libraries=no + + +Use +--- + +Make sure the library is installed on your LUA_CPATH, and require it. + +The library provides the constant bit.bits that gives the number of +bits that can be used in bitwise operations, and the following +functions: + +bit.cast(a) cast a to the internally-used integer type +bit.bnot(a) returns the one's complement of a +bit.band(w1, ...) returns the bitwise and of the w's +bit.bor(w1, ...) returns the bitwise or of the w's +bit.bxor(w1, ...) returns the bitwise exclusive or of the w's +bit.lshift(a, b) returns a shifted left b places +bit.rshift(a, b) returns a shifted logically right b places +bit.arshift(a, b) returns a shifted arithmetically right b places + +All function arguments should be integers that fit into the C type +lua_Integer. + +The logical operations start with "b" for "bit" to avoid clashing with +reserved words; although "xor" isn't a reserved word, it seemed better +to use "bxor" for consistency. diff --git a/client/cmdscript.c b/client/cmdscript.c index 8c1acf27..928a216d 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -25,7 +25,7 @@ #include "cmdscript.h" #include "cmdhfmf.h" #include "pm3_binlib.h" - +#include "pm3_bitlib.h" #include #include #include @@ -133,6 +133,8 @@ int CmdRun(const char *Cmd) //Add the 'bin' library set_bin_library(lua_state); + //Add the 'bit' library + set_bit_library(lua_state); char script_name[128] = {0}; char arguments[256] = {0}; diff --git a/client/pm3_bit_limits.h b/client/pm3_bit_limits.h new file mode 100644 index 00000000..943b2fd7 --- /dev/null +++ b/client/pm3_bit_limits.h @@ -0,0 +1,4 @@ +#define BITLIB_FLOAT_BITS 53 +#define BITLIB_FLOAT_MAX 0xfffffffffffffL +#define BITLIB_FLOAT_MIN (-0x10000000000000L) +#define BITLIB_FLOAT_UMAX 0x1fffffffffffffUL diff --git a/client/pm3_bitlib.c b/client/pm3_bitlib.c new file mode 100644 index 00000000..29fc49f1 --- /dev/null +++ b/client/pm3_bitlib.c @@ -0,0 +1,152 @@ +/* Bitwise operations library */ +/* (c) Reuben Thomas 2000-2008 */ +/* See README for license */ + +#include +#include +#include + +#include "pm3_bit_limits.h" + + +/* FIXME: Assumes lua_Integer is ptrdiff_t */ +#define LUA_INTEGER_MAX PTRDIFF_MAX +#define LUA_INTEGER_MIN PTRDIFF_MIN + +/* FIXME: Assumes size_t is an unsigned lua_Integer */ +typedef size_t lua_UInteger; +#define LUA_UINTEGER_MAX SIZE_MAX + + +/* Bit type size and limits */ + +#define BIT_BITS \ + (CHAR_BIT * sizeof(lua_Integer) > BITLIB_FLOAT_BITS ? \ + BITLIB_FLOAT_BITS : (CHAR_BIT * sizeof(lua_Integer))) + +/* This code may give warnings if BITLIB_FLOAT_* are too big to fit in + long, but that doesn't matter since in that case they won't be + used. */ +#define BIT_MAX \ + (CHAR_BIT * sizeof(lua_Integer) > BITLIB_FLOAT_BITS ? BITLIB_FLOAT_MAX : LUA_INTEGER_MAX) + +#define BIT_MIN \ + (CHAR_BIT * sizeof(lua_Integer) > BITLIB_FLOAT_BITS ? BITLIB_FLOAT_MIN : LUA_INTEGER_MIN) + +#define BIT_UMAX \ + (CHAR_BIT * sizeof(lua_Integer) > BITLIB_FLOAT_BITS ? BITLIB_FLOAT_UMAX : LUA_UINTEGER_MAX) + + +/* Define TOBIT to get a bit value */ +#ifdef BUILTIN_CAST +#define +#define TOBIT(L, n, res) \ + ((void)(res), luaL_checkinteger((L), (n))) +#else +#include +#include + +/* FIXME: Assumes lua_Number fits in a double (use of fmod). */ +#define TOBIT(L, n, res) \ + ((lua_Integer)(((res) = fmod(luaL_checknumber(L, (n)), (double)BIT_UMAX + 1.0)), \ + (res) > BIT_MAX ? ((res) -= (double)BIT_UMAX, (res) -= 1) : \ + ((res) < BIT_MIN ? ((res) += (double)BIT_UMAX, (res) += 1) : (res)))) +#endif + + +#define BIT_TRUNCATE(i) \ + ((i) & BIT_UMAX) + + +/* Operations + + The macros MONADIC and VARIADIC only deal with bitwise operations. + + LOGICAL_SHIFT truncates its left-hand operand before shifting so + that any extra bits at the most-significant end are not shifted + into the result. + + ARITHMETIC_SHIFT does not truncate its left-hand operand, so that + the sign bits are not removed and right shift work properly. + */ + +#define MONADIC(name, op) \ + static int bit_ ## name(lua_State *L) { \ + lua_Number f; \ + lua_pushinteger(L, BIT_TRUNCATE(op TOBIT(L, 1, f))); \ + return 1; \ + } + +#define VARIADIC(name, op) \ + static int bit_ ## name(lua_State *L) { \ + lua_Number f; \ + int n = lua_gettop(L), i; \ + lua_Integer w = TOBIT(L, 1, f); \ + for (i = 2; i <= n; i++) \ + w op TOBIT(L, i, f); \ + lua_pushinteger(L, BIT_TRUNCATE(w)); \ + return 1; \ + } + +#define LOGICAL_SHIFT(name, op) \ + static int bit_ ## name(lua_State *L) { \ + lua_Number f; \ + lua_pushinteger(L, BIT_TRUNCATE(BIT_TRUNCATE((lua_UInteger)TOBIT(L, 1, f)) op \ + (unsigned)luaL_checknumber(L, 2))); \ + return 1; \ + } + +#define ARITHMETIC_SHIFT(name, op) \ + static int bit_ ## name(lua_State *L) { \ + lua_Number f; \ + lua_pushinteger(L, BIT_TRUNCATE((lua_Integer)TOBIT(L, 1, f) op \ + (unsigned)luaL_checknumber(L, 2))); \ + return 1; \ + } + +MONADIC(cast, +) +MONADIC(bnot, ~) +VARIADIC(band, &=) +VARIADIC(bor, |=) +VARIADIC(bxor, ^=) +ARITHMETIC_SHIFT(lshift, <<) +LOGICAL_SHIFT(rshift, >>) +ARITHMETIC_SHIFT(arshift, >>) + +static const struct luaL_Reg bitlib[] = { + {"cast", bit_cast}, + {"bnot", bit_bnot}, + {"band", bit_band}, + {"bor", bit_bor}, + {"bxor", bit_bxor}, + {"lshift", bit_lshift}, + {"rshift", bit_rshift}, + {"arshift", bit_arshift}, + {NULL, NULL} +}; + +LUALIB_API int luaopen_bit (lua_State *L) { + luaL_newlib(L, bitlib); + //luaL_register(L, "bit", bitlib); + lua_pushnumber(L, BIT_BITS); + lua_setfield(L, -2, "bits"); + return 1; +} + +/** +LUALIB_API int luaopen_bit (lua_State *L) { + luaL_register(L, "bit", bitlib); + lua_pushnumber(L, BIT_BITS); + lua_setfield(L, -2, "bits"); + return 1; +} +**/ +/* +** Open bit library +*/ +int set_bit_library (lua_State *L) { + + luaL_requiref(L, "bit", luaopen_bit, 1); + lua_pop(L, 1); + return 1; +} diff --git a/client/pm3_bitlib.h b/client/pm3_bitlib.h new file mode 100644 index 00000000..45da0a34 --- /dev/null +++ b/client/pm3_bitlib.h @@ -0,0 +1,7 @@ +#ifndef PM3_BITLIB +#define PM3_BITLIB + +#include +int set_bit_library (lua_State *L); + +#endif /* PM3_BITLIB */ diff --git a/client/scripting.c b/client/scripting.c index 43474b98..963bb64c 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -17,7 +17,7 @@ #include "scripting.h" #include "util.h" #include "nonce2key/nonce2key.h" - +#include "../common/iso15693tools.h" /** * The following params expected: * UsbCommand c @@ -214,6 +214,15 @@ static int l_CmdConsole(lua_State *L) return 0; } +static int l_iso15693_crc(lua_State *L) +{ + // uint16_t Iso15693Crc(uint8_t *v, int n); + size_t size; + const char *v = luaL_checklstring(L, 1, &size); + uint16_t retval = Iso15693Crc((uint8_t *) v, size); + lua_pushinteger(L, (int) retval); + return 1; +} /** * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be @@ -251,6 +260,7 @@ int set_pm3_libraries(lua_State *L) {"ukbhit", l_ukbhit}, {"clearCommandBuffer", l_clearCommandBuffer}, {"console", l_CmdConsole}, + {"iso15693_crc", l_iso15693_crc}, {NULL, NULL} }; -- 2.39.2