00001 #include "lua_bindings.h" 00002 00003 #include "ac_app_context.h" 00004 #include "application_config.h" 00005 #include "cf_rcfile.h" 00006 #include "kr_controller_private.h" 00007 #include "lua_cl2.h" 00008 #include "sa_sensor_list_integration.h" 00009 #include "sa_sensor_list_log_db.h" 00010 #include "utils_cl2.h" 00011 00012 #if defined(__SYMBIAN32__) 00013 #include "epoc-iap.h" 00014 #endif /* __SYMBIAN32__ */ 00015 00016 #include "lua.hpp" 00017 00018 // xxx A lot of Lua bindings do not appear to check if they are given 00019 // the correct number of arguments, and we are not doing that either. 00020 // We might want to start doing so at some point. 00021 #define luai_check(L, cond) { if (!(cond)) { } } // xxx how to report 00022 #define luai_checknelems(L, n) luai_check(L, (n) <= (L->top - L->base)) 00023 00024 static int lua_error_unsupported(lua_State* L) 00025 { 00026 lua_pushstring(L, "unsupported"); 00027 lua_error(L); // will not return 00028 return 0; // to avoid warnings 00029 } 00030 00031 #define throw_error_unsupported { return lua_error_unsupported(L); } 00032 00033 /***koog (require codegen/lua-c) ***//***end***/ 00034 00035 /***koog (lua-func static_get_str) ***/ 00036 static int f_static_get_str(lua_State* L) 00037 /***end***/ 00038 { 00039 const char* name = luaL_checklstring(L, 1, NULL); 00040 const char* value = cf_RcFile_get_str_maybe(ac_global_RcFile, name); 00041 if (value) 00042 lua_pushstring(L, value); 00043 else 00044 lua_pushnil(L); 00045 return 1; 00046 } 00047 /* 00048 -- It seems okay to reenter the same Lua VM via a binding. 00049 -- Try putting this in the config file, and then 00050 -- remotely doing return cl2.static_get_str('foo') 00051 foo = function () return cl2.static_get_str('bar') end 00052 bar = function () return cl2.static_get_str('baz') end 00053 baz = "bamf" 00054 */ 00055 00056 /***koog (lua-func throw_unsupported) ***/ 00057 static int f_throw_unsupported(lua_State* L) 00058 /***end***/ 00059 { 00060 throw_error_unsupported; 00061 } 00062 00063 /***koog (lua-func die_now) ***/ 00064 static int f_die_now(lua_State* L) 00065 /***end***/ 00066 { 00067 (void)L; 00068 EXIT_APPLICATION; 00069 return 0; 00070 } 00071 00072 /***koog (lua-func shutdown) ***/ 00073 static int f_shutdown(lua_State* L) 00074 /***end***/ 00075 { 00076 (void)L; 00077 SHUTDOWN_APPLICATION; 00078 return 0; 00079 } 00080 00081 /***koog (lua-func log) ***/ 00082 static int f_log(lua_State* L) 00083 /***end***/ 00084 { 00085 (void)L; 00086 #if __DO_LOGGING__ 00087 const char* text = luaL_checklstring(L, 1, NULL); 00088 logt(text); 00089 #endif 00090 return 0; 00091 } 00092 00093 /***koog (lua-func is_ascii_ident) ***/ 00094 static int f_is_ascii_ident(lua_State* L) 00095 /***end***/ 00096 { 00097 const char* s = luaL_checklstring(L, 1, NULL); 00098 gboolean is_so = is_ascii_ident(s); 00099 lua_pushboolean(L, is_so); 00100 return 1; 00101 } 00102 00103 /***koog (lua-func iap_id_by_name) ***/ 00104 static int f_iap_id_by_name(lua_State* L) 00105 /***end***/ 00106 { 00107 #if !defined(__SYMBIAN32__) 00108 throw_error_unsupported; 00109 #else 00110 // When Lua invokes a C function a fresh new stack will be used; 00111 // hence our sole argument will be the only item on the stack; 00112 // hence here narg -1 and 1 both point to said argument. 00113 const char* iapName = luaL_checklstring(L, 1, NULL); 00114 guint32 iapId = 0; 00115 gboolean found = FALSE; 00116 GError* iapError = NULL; 00117 gboolean success = epoc_iap_by_name(iapName, &iapId, &found, &iapError); 00118 lua_pop(L, 1); // iapName (must pop arg before pushing results) 00119 if (success) { 00120 if (found) { 00121 lua_pushinteger(L, iapId); 00122 } else { 00123 lua_pushnil(L); 00124 } 00125 } else { 00126 lua_raise_gerror(L, iapError); 00127 } 00128 return 1; 00129 #endif /* __SYMBIAN32__ */ 00130 } 00131 00132 /***koog (lua-func get_username) ***/ 00133 static int f_get_username(lua_State* L) 00134 /***end***/ 00135 { 00136 const char* name = cf_RcFile_get_username(ac_global_RcFile); 00137 lua_pushstring(L, name); 00138 return 1; 00139 } 00140 00141 /***koog (lua-func config_get) ***/ 00142 static int f_config_get(lua_State* L) 00143 /***end***/ 00144 { 00145 // xxx should we check that the number of arguments is right 00146 const char* name = luaL_checklstring(L, 1, NULL); 00147 GError* getError = NULL; 00148 char* value = ac_DYNAMIC_GET_ERR(name, &getError); 00149 lua_pop(L, 1); // name 00150 if (value) { 00151 lua_pushstring(L, value); 00152 g_free(value); 00153 } else if (is_not_found_error(getError)) { 00154 g_error_free(getError); 00155 lua_pushnil(L); 00156 } else { 00157 lua_raise_gerror(L, getError); 00158 } 00159 return 1; 00160 } 00161 00162 /***koog (lua-func config_set) ***/ 00163 static int f_config_set(lua_State* L) 00164 /***end***/ 00165 { 00166 const char* name = luaL_checklstring(L, 1, NULL); 00167 const char* value = luaL_checklstring(L, 2, NULL); 00168 logg("config set '%s' -> '%s'", name, value); 00169 GError* setError = NULL; 00170 gboolean success = ac_DYNAMIC_SET_ERR(name, value, &setError); 00171 lua_pop(L, 2); // name, value (perhaps unnecessary) 00172 if (!success) { 00173 logt("config set failed"); 00174 return lua_raise_gerror(L, setError); 00175 } else { 00176 logt("config set ok"); 00177 } 00178 return 0; 00179 } 00180 00181 /***koog (lua-func all_sensor_names) ***/ 00182 static int f_all_sensor_names(lua_State* L) 00183 /***end***/ 00184 // Lists _all_ known sensors, whether supported by the build or not. 00185 // Filter using is_sensor_supported as necessary. 00186 { 00187 const char* names[] = ALL_SENSOR_NAMES_LITERAL_LIST; // do not duplicate this in many places 00188 lua_createtable(L, NUM_ALL_SENSORS, 0); // at Lua stack index 1 00189 for (int i = 0; i < NUM_ALL_SENSORS; i++) 00190 { 00191 lua_pushstring(L, names[i]); 00192 lua_rawseti(L, 1, i + 1); // Lua indexes start from 1 00193 } 00194 return 1; // return the table 00195 } 00196 00197 /***koog (lua-func is_sensor_supported) ***/ 00198 static int f_is_sensor_supported(lua_State* L) 00199 /***end***/ 00200 { 00201 const char* name = luaL_checklstring(L, 1, NULL); 00202 gboolean is_so = sa_sensor_is_supported(name); 00203 lua_pushboolean(L, is_so); 00204 return 1; 00205 } 00206 00207 /***koog (lua-func is_sensor_running) ***/ 00208 static int f_is_sensor_running(lua_State* L) 00209 /***end***/ 00210 { 00211 const char* name = luaL_checklstring(L, 1, NULL); 00212 kr_Controller* kr = ac_global_Controller; 00213 gboolean is_so = sa_Array_sensor_is_running(kr->scanner, name); 00214 lua_pushboolean(L, is_so); 00215 return 1; 00216 } 00217 00218 /***koog (lua-func sensor_stop) ***/ 00219 static int f_sensor_stop(lua_State* L) 00220 /***end***/ 00221 { 00222 const char* name = luaL_checklstring(L, 1, NULL); 00223 kr_Controller* kr = ac_global_Controller; 00224 sa_Array_sensor_stop(kr->scanner, name); 00225 return 0; 00226 } 00227 00228 /***koog (lua-func sensor_start) ***/ 00229 static int f_sensor_start(lua_State* L) 00230 /***end***/ 00231 { 00232 const char* name = luaL_checklstring(L, 1, NULL); 00233 kr_Controller* kr = ac_global_Controller; 00234 GError* localError = NULL; 00235 if (!sa_Array_sensor_start(kr->scanner, name, &localError)) { 00236 return lua_raise_gerror(L, localError); 00237 } 00238 return 0; 00239 } 00240 00241 /***koog (lua-func upload_now) ***/ 00242 static int f_upload_now(lua_State* L) 00243 /***end***/ 00244 { 00245 #if __FEATURE_UPLOADER__ 00246 kr_Controller* kr = ac_global_Controller; 00247 if (!kr->uploader) { 00248 lua_pushstring(L, "uploader not started"); 00249 lua_error(L); // will not return 00250 } 00251 GError* localError = NULL; 00252 if (!up_Uploader_upload_now(kr->uploader, &localError)) { 00253 return lua_raise_gerror(L, localError); 00254 } 00255 #else 00256 lua_error_unsupported(L); 00257 #endif 00258 return 0; 00259 } 00260 00261 /***koog (lua-func get_upload_time) ***/ 00262 static int f_get_upload_time(lua_State* L) 00263 /***end***/ 00264 { 00265 time_t t = ac_global_Registry->last_upload_time; 00266 if (t == 0) { 00267 lua_pushnil(L); 00268 } else { 00269 lua_pushinteger(L, t); 00270 } 00271 return 1; 00272 } 00273 00274 /***koog (lua-func remokon_start) ***/ 00275 static int f_remokon_start(lua_State* L) 00276 /***end***/ 00277 { 00278 #if __FEATURE_REMOKON__ 00279 kr_Controller* kr = ac_global_Controller; 00280 GError* localError = NULL; 00281 if (!rk_Remokon_start(kr->remokon, &localError)) { 00282 return lua_raise_gerror(L, localError); 00283 } 00284 #else 00285 lua_error_unsupported(L); 00286 #endif 00287 return 0; 00288 } 00289 00290 /***koog (lua-func remokon_timed) ***/ 00291 static int f_remokon_timed(lua_State* L) 00292 /***end***/ 00293 { 00294 #if __FEATURE_REMOKON__ 00295 int secs = luaL_checkint(L, 1); 00296 kr_Controller* kr = ac_global_Controller; 00297 GError* localError = NULL; 00298 if (!rk_Remokon_start_timed(kr->remokon, secs, &localError)) { 00299 return lua_raise_gerror(L, localError); 00300 } 00301 #else 00302 lua_error_unsupported(L); 00303 #endif 00304 return 0; 00305 } 00306 00307 /***koog (lua-func remokon_stop) ***/ 00308 static int f_remokon_stop(lua_State* L) 00309 /***end***/ 00310 { 00311 #if __FEATURE_REMOKON__ 00312 kr_Controller* kr = ac_global_Controller; 00313 rk_Remokon_stop(kr->remokon); 00314 #else 00315 lua_error_unsupported(L); 00316 #endif 00317 return 0; 00318 } 00319 00320 /***koog (lua-func log_message) ***/ 00321 static int f_log_message(lua_State* L) 00322 /***end***/ 00323 { 00324 #if __APPMESSAGE_ENABLED__ 00325 const char* msgText = luaL_checklstring(L, 1, NULL); 00326 GError* localError = NULL; 00327 if (!log_db_log_appmessage(ac_global_LogDb, msgText, &localError)) { 00328 return lua_raise_gerror(L, localError); 00329 } 00330 #else 00331 lua_error_unsupported(L); 00332 #endif 00333 return 0; 00334 } 00335 00336 /***koog (lua-func are_uploads_allowed) ***/ 00337 static int f_are_uploads_allowed(lua_State* L) 00338 /***end***/ 00339 { 00340 kr_Controller* kr = ac_global_Controller; 00341 lua_pushboolean(L, kr->are_uploads_allowed); 00342 return 1; 00343 } 00344 00345 static const luaL_Reg function_table[] = { 00346 /***koog (lua-entries) ***/ 00347 {"are_uploads_allowed", f_are_uploads_allowed}, 00348 {"log_message", f_log_message}, 00349 {"remokon_stop", f_remokon_stop}, 00350 {"remokon_timed", f_remokon_timed}, 00351 {"remokon_start", f_remokon_start}, 00352 {"get_upload_time", f_get_upload_time}, 00353 {"upload_now", f_upload_now}, 00354 {"sensor_start", f_sensor_start}, 00355 {"sensor_stop", f_sensor_stop}, 00356 {"is_sensor_running", f_is_sensor_running}, 00357 {"is_sensor_supported", f_is_sensor_supported}, 00358 {"all_sensor_names", f_all_sensor_names}, 00359 {"config_set", f_config_set}, 00360 {"config_get", f_config_get}, 00361 {"get_username", f_get_username}, 00362 {"iap_id_by_name", f_iap_id_by_name}, 00363 {"is_ascii_ident", f_is_ascii_ident}, 00364 {"log", f_log}, 00365 {"shutdown", f_shutdown}, 00366 {"die_now", f_die_now}, 00367 {"throw_unsupported", f_throw_unsupported}, 00368 {"static_get_str", f_static_get_str}, 00369 /***end***/ 00370 {NULL, NULL} 00371 }; 00372 00373 extern "C" int luaopen_cl2(lua_State *L) 00374 { 00375 luaL_register(L, LUA_CL2LIBNAME, function_table); 00376 00377 /* 00378 lua_pushnumber(L, __VERSION100__); 00379 lua_setfield(L, -2, "version"); 00380 */ 00381 00382 lua_pushstring(L, __APP_NAME__); 00383 lua_setfield(L, -2, "app_name"); 00384 00385 lua_pushstring(L, __VERSION_STRING__); 00386 lua_setfield(L, -2, "app_version"); 00387 00388 lua_pushstring(L, __VARIANT_NAME__); 00389 lua_setfield(L, -2, "app_variant"); 00390 00391 lua_pushstring(L, __COMPILER_NAME__); 00392 lua_setfield(L, -2, "compiler_name"); 00393 00394 #if defined(__GNUC__) 00395 lua_pushfstring(L, "%d.%d.%d", 00396 __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); 00397 #else 00398 lua_pushnil(L); 00399 #endif 00400 lua_setfield(L, -2, "compiler_version"); 00401 00402 #if defined(NDEBUG) 00403 lua_pushstring(L, "release"); 00404 #else 00405 lua_pushstring(L, "debug"); 00406 #endif 00407 lua_setfield(L, -2, "build_type"); 00408 00409 return 1; 00410 } 00411 00412 /** 00413 00414 lua_bindings.cpp 00415 00416 Copyright 2009 Helsinki Institute for Information Technology (HIIT) 00417 and the authors. All rights reserved. 00418 00419 Authors: Tero Hasu <tero.hasu@hut.fi> 00420 00421 Permission is hereby granted, free of charge, to any person 00422 obtaining a copy of this software and associated documentation files 00423 (the "Software"), to deal in the Software without restriction, 00424 including without limitation the rights to use, copy, modify, merge, 00425 publish, distribute, sublicense, and/or sell copies of the Software, 00426 and to permit persons to whom the Software is furnished to do so, 00427 subject to the following conditions: 00428 00429 The above copyright notice and this permission notice shall be 00430 included in all copies or substantial portions of the Software. 00431 00432 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00433 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00434 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00435 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 00436 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 00437 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00438 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00439 SOFTWARE. 00440 00441 **/
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:55 2011 by Doxygen 1.6.1