X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/5b760b6cac721c6abd036c0689e713b5a7c700c5..6a2c1d8e1451df63aaab3790a3c2d97afb74b89b:/client/scripting.c diff --git a/client/scripting.c b/client/scripting.c index f9f4999d..ae11d7ca 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -15,6 +15,7 @@ #include "usb_cmd.h" #include "cmdmain.h" #include "scripting.h" +#include "util.h" /** * The following params expected: * UsbCommand c @@ -40,10 +41,18 @@ static int l_SendCommand(lua_State *L){ ==> A 544 byte buffer will do. **/ //Pop cmd - UsbCommand *c = (UsbCommand *)lua_touserdata(L, 1); - luaL_argcheck(L, c != NULL, 1, "'UsbCommand' expected"); - SendCommand(c); - return 0; + size_t size; + const char *data = luaL_checklstring(L, 1, &size); + if(size != sizeof(UsbCommand)) + { + printf("Got data size %d, expected %d" , (int) size,(int) sizeof(UsbCommand)); + lua_pushstring(L,"Wrong data size"); + return 1; + } + +// UsbCommand c = (*data); + SendCommand((UsbCommand* )data); + return 0; // no return values } /** * @brief The following params expected: @@ -54,52 +63,115 @@ static int l_SendCommand(lua_State *L){ */ static int l_WaitForResponseTimeout(lua_State *L){ - //pop cmd - uint32_t cmd = luaL_checkunsigned(L,1); - printf("in l_WaitForResponseTimeout, got cmd 0x%0x\n",(int) cmd); - //UsbCommand response; - - //We allocate the usbcommand as userdata on the Lua-stack - size_t nbytes = sizeof(UsbCommand); + uint32_t cmd = 0; + size_t ms_timeout = -1; - UsbCommand *response = (UsbCommand *)lua_newuserdata(L, nbytes); - - size_t ms_timeout = 2000; - //Did the user send a timeout ? - //Check if the current top of stack is an integer - - if(lua_isnumber( L, 2)) + //Check number of arguments + int n = lua_gettop(L); + if(n == 0) + { + //signal error by returning Nil, errorstring + lua_pushnil(L); + lua_pushstring(L,"You need to supply at least command to wait for"); + return 2; // two return values + } + if(n >= 1) { - printf("You sent a timout-value\n"); + //pop cmd + cmd = luaL_checkunsigned(L,1); + } + if(n >= 2) + { + //Did the user send a timeout ? + //Check if the current top of stack is an integer ms_timeout = luaL_checkunsigned(L,2); + //printf("Timeout set to %dms\n" , (int) ms_timeout); } - printf("Timeout set to %dms\n" , (int) ms_timeout); - if(WaitForResponseTimeout(cmd, response, ms_timeout)) - { - //Return the UsbCommand as userdata - //the usbcommand is already on the stack - // return 1 to signal one return value - return 1; - }else + UsbCommand response; + + if(WaitForResponseTimeout(cmd, &response, ms_timeout)) { - //Don't return the UsbCommand. Pop it. - lua_pop(L,-1); + //Push it as a string + lua_pushlstring(L,(const char *)&response,sizeof(UsbCommand)); + + return 1;// return 1 to signal one return value + }else{ //Push a Nil instead lua_pushnil(L); - return 1; + return 1;// one return value } } -static int l_nonce2key(lua_State *L){ return CmdHF14AMfRdSc(luaL_checkstring(L, 1));} -static int l_PrintAndLog(lua_State *L){ return CmdHF14AMfDump(luaL_checkstring(L, 1));} +//static int l_nonce2key(lua_State *L){ return CmdHF14AMfRdSc(luaL_checkstring(L, 1));} +//static int l_PrintAndLog(lua_State *L){ return CmdHF14AMfDump(luaL_checkstring(L, 1));} +static int l_clearCommandBuffer(lua_State *L){ + clearCommandBuffer(); + return 0; +} +/** + * @brief l_foobar is a dummy function to test lua-integration with + * @param L + * @return + */ +static int l_foobar(lua_State *L) +{ + //Check number of arguments + int n = lua_gettop(L); + printf("foobar called with %d arguments" , n); + lua_settop(L, 0); + printf("Arguments discarded, stack now contains %d elements", lua_gettop(L)); + UsbCommand response = {CMD_MIFARE_READBL, {1337, 1338, 1339}}; + printf("Now returning a UsbCommand as a string"); + lua_pushlstring(L,(const char *)&response,sizeof(UsbCommand)); + return 1; +} + +/** + * @brief Utility to check if a key has been pressed by the user. This method does not block. + * @param L + * @return boolean, true if kbhit, false otherwise. + */ +static int l_ukbhit(lua_State *L) +{ + lua_pushboolean(L,ukbhit() ? true : false); + return 1; +} -void set_pm3_libraries(lua_State *L) +/** + * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be + * able to do "require('foobar')" if foobar.lua is within lualibs folder. + * Taken from http://stackoverflow.com/questions/4125971/setting-the-global-lua-path-variable-from-c-c + * @param L + * @param path + * @return + */ +int setLuaPath( lua_State* L, const char* path ) { + lua_getglobal( L, "package" ); + lua_getfield( L, -1, "path" ); // get field "path" from table at top of stack (-1) + const char* cur_path = lua_tostring( L, -1 ); // grab path string from top of stack + int requiredLength = strlen(cur_path)+ strlen(path)+10; //A few bytes too many, whatever we can afford it + char * buf = malloc(requiredLength); + snprintf(buf, requiredLength, "%s;%s", cur_path, path); + lua_pop( L, 1 ); // get rid of the string on the stack we just pushed on line 5 + lua_pushstring( L, buf ); // push the new one + lua_setfield( L, -2, "path" ); // set the field "path" in table at -2 with value at top of stack + lua_pop( L, 1 ); // get rid of package table from top of stack + return 0; // all done! +} + + +int set_pm3_libraries(lua_State *L) +{ + static const luaL_Reg libs[] = { {"SendCommand", l_SendCommand}, {"WaitForResponseTimeout", l_WaitForResponseTimeout}, - {"nonce2key", l_nonce2key}, - {"PrintAndLog", l_PrintAndLog}, + //{"nonce2key", l_nonce2key}, + //{"PrintAndLog", l_PrintAndLog}, + {"foobar", l_foobar}, + {"ukbhit", l_ukbhit}, + {"clearCommandBuffer", l_clearCommandBuffer}, {NULL, NULL} }; @@ -118,5 +190,10 @@ void set_pm3_libraries(lua_State *L) //-- remove the global environment table from the stack lua_pop(L, 1); + + //-- Last but not least, add to the LUA_PATH (package.path in lua) + // so we can load libraries from the ./lualib/ - directory + setLuaPath(L,"./lualibs/?.lua"); + return 1; }