├── .gitignore ├── Doxyfile ├── LICENSE.txt ├── Makefile.am ├── README.md ├── SYMBOLS.txt ├── configure.ac ├── include └── openlipc.h ├── src ├── Makefile.am ├── lipc-get-prop.c ├── lipc-probe.c └── lipc-set-prop.c └── test ├── Makefile.am ├── lipc-test-event.c ├── lipc-test-hasharray.c ├── lipc-test-init.c └── lipc-test-prop.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Libraries 8 | *.lib 9 | *.a 10 | 11 | # Shared objects (inc. Windows DLLs) 12 | *.dll 13 | *.so 14 | *.so.* 15 | *.dylib 16 | 17 | # Executables 18 | *.exe 19 | *.out 20 | *.app 21 | *.i*86 22 | *.x86_64 23 | *.hex 24 | 25 | # Autotools 26 | /autom4te.cache/ 27 | /build*/ 28 | /aclocal.m4 29 | /compile 30 | /configure 31 | /depcomp 32 | /install-sh 33 | /missing 34 | /test-driver 35 | Makefile.in 36 | config.h.in 37 | *~ 38 | -------------------------------------------------------------------------------- /Doxyfile: -------------------------------------------------------------------------------- 1 | # Doxyfile 1.8.10 2 | 3 | # This file describes the settings to be used by the documentation system 4 | # doxygen (www.doxygen.org) for a project. 5 | 6 | #--------------------------------------------------------------------------- 7 | # Project related configuration options 8 | #--------------------------------------------------------------------------- 9 | 10 | PROJECT_NAME = [open]lipc 11 | PROJECT_BRIEF = "Open-source LIPC header file" 12 | 13 | #--------------------------------------------------------------------------- 14 | # Build related configuration options 15 | #--------------------------------------------------------------------------- 16 | 17 | INPUT = include 18 | OUTPUT_DIRECTORY = doc 19 | 20 | OPTIMIZE_OUTPUT_FOR_C = YES 21 | INLINE_GROUPED_CLASSES = YES 22 | INLINE_SIMPLE_STRUCTS = YES 23 | TYPEDEF_HIDES_STRUCT = YES 24 | SORT_MEMBER_DOCS = NO 25 | 26 | HIDE_SCOPE_NAMES = YES 27 | HIDE_COMPOUND_REFERENCE= YES 28 | SHOW_USED_FILES = NO 29 | SHOW_FILES = NO 30 | SHOW_NAMESPACES = NO 31 | 32 | #--------------------------------------------------------------------------- 33 | # Configuration options related to the HTML output 34 | #--------------------------------------------------------------------------- 35 | 36 | GENERATE_HTML = YES 37 | HTML_TIMESTAMP = YES 38 | ENUM_VALUES_PER_LINE = 1 39 | SEARCHENGINE = NO 40 | 41 | #--------------------------------------------------------------------------- 42 | # Configuration options related to the LaTeX output 43 | #--------------------------------------------------------------------------- 44 | 45 | GENERATE_LATEX = NO 46 | 47 | #--------------------------------------------------------------------------- 48 | # Configuration options related to the man page output 49 | #--------------------------------------------------------------------------- 50 | 51 | GENERATE_MAN = YES 52 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2016 Arkadiusz Bokowy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # [open]lipc - Makefile.am 2 | # Copyright (c) 2016 Arkadiusz Bokowy 3 | 4 | SUBDIRS = src test 5 | 6 | include_HEADERS = include/openlipc.h 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [open]lipc - open-source LIPC 2 | ============================= 3 | 4 | LIPC seems to be an IPC library based on D-Bus. It links all Kindle components together. Via this 5 | library one is able to expose application properties/settings, listen for or emit events, and many 6 | more (potentially). It is considered to be one of the core components of the Kindle device. 7 | 8 | This project is a reverse-engineered [header file](/include/openlipc.h) for this library. Since 9 | the header file itself might be not enough, some auxiliary tools (e.g. lipc-get-prop, lipc-probe) 10 | has been also reconstructed. They intend to be full replacements for the original ones (with few 11 | modifications and enhancements). 12 | 13 | For usage information consult the online [reference manual](https://arkq.github.io/openlipc/). 14 | 15 | 16 | Installation 17 | ------------ 18 | 19 | $ autoreconf --install 20 | $ ./configure --without-lipc-prop --without-lipc-probe 21 | $ make && make install 22 | 23 | Or simply copy the header file into the system's include directory (e.g. /usr/include/). 24 | 25 | If you want to compile exemplary tools as well, consider using steps as follows (assuming you are 26 | performing cross-compilation, if not, omit all options for the configure step): 27 | 28 | $ autoreconf --install 29 | $ mkdir build && cd build 30 | $ export KINDLE_ROOTDIR= 31 | $ ../configure --enable-kindle-env --host=armv7a-softfp-linux-gnueabi 32 | $ make && make install 33 | 34 | 35 | Acknowledgment 36 | -------------- 37 | 38 | This project was inspired by the work of Bartek Fabiszewski, who has also reverse-engineered this 39 | library. His [work](https://github.com/bfabiszewski/openlipc) was a starting point for my further 40 | investigations. 41 | -------------------------------------------------------------------------------- /SYMBOLS.txt: -------------------------------------------------------------------------------- 1 | This file contains listing of all global symbols available in the proprietary 2 | LIPC library shipped with the Kindle Touch firmware 5.3.7.3. 3 | 4 | Symbols available in the openlipc.h header file: 5 | 6 | - LipcAddIntParam 7 | - LipcAddStringParam 8 | - LipcClose 9 | - LipcCreateAndSendEvent 10 | - LipcCreateAndSendEventWithParameters 11 | - LipcCreateAndSendEventWithVAListParameters 12 | - LipcEventFree 13 | - LipcFreeString 14 | - LipcGetErrorString 15 | - LipcGetEventName 16 | - LipcGetEventSource 17 | - LipcGetIntParam 18 | - LipcGetIntProperty 19 | - LipcGetPropAccessTimeout 20 | - LipcGetServiceName 21 | - LipcGetStringParam 22 | - LipcGetStringProperty 23 | - LipcHasharrayAddHash 24 | - LipcHasharrayCheckKey 25 | - LipcHasharrayClone 26 | - LipcHasharrayCopy 27 | - LipcHasharrayCopyHash 28 | - LipcHasharrayDestroy 29 | - LipcHasharrayFree 30 | - LipcHasharrayGetBlob 31 | - LipcHasharrayGetHashCount 32 | - LipcHasharrayGetInt 33 | - LipcHasharrayGetString 34 | - LipcHasharrayKeys 35 | - LipcHasharrayNew 36 | - LipcHasharrayPutBlob 37 | - LipcHasharrayPutInt 38 | - LipcHasharrayPutString 39 | - LipcHasharrayRestore 40 | - LipcHasharraySave 41 | - LipcHasharrayToString 42 | - LipcNewEvent 43 | - LipcOpen 44 | - LipcOpenEx 45 | - LipcOpenNoName 46 | - LipcRegisterIntProperty 47 | - LipcRegisterStringProperty 48 | - LipcRewindParams 49 | - LipcSendEvent 50 | - LipcSetEventCallback 51 | - LipcSetIntProperty 52 | - LipcSetLlog 53 | - LipcSetStringProperty 54 | - LipcSubscribe 55 | - LipcSubscribeExt 56 | - LipcUnregisterProperty 57 | - LipcUnsubscribeExt 58 | - g_lab126_log_mask 59 | 60 | Undocumented (not yet) symbols: 61 | 62 | - LipcAccessHasharrayProperty 63 | - LipcAccessPropertyAsync 64 | - LipcCbPush 65 | - LipcCbThreadDeinit 66 | - LipcCbThreadInit 67 | - LipcDeInitPropertyHandling 68 | - LipcEnsureBusReadyForWrite 69 | - LipcHasharrayGetKey 70 | - LipcHasharrayPrepareToSend 71 | - LipcHasharrayReconstruct 72 | - LipcInitPropertyHandling 73 | - LipcPrepareFdSetsFromWatches 74 | - LipcProcessMethod 75 | - LipcProcessReply 76 | - LipcProcessSignal 77 | - LipcRegisterHasharrayProperties 78 | - LipcRegisterHasharrayProperty 79 | - LipcRegisterIntProperties 80 | - LipcRegisterStringProperties 81 | - LipcSubscribeExtMulti 82 | - PrvAddRemoveMatchRule 83 | - PrvCreatePublisherEventKey 84 | - PrvDBusRemoveWatch 85 | - PrvDBusWatchToggled 86 | - PrvDbusAddWatch 87 | - PrvEventCallback 88 | - PrvGetPropAccessTimeout 89 | - PrvHashElementDestroy 90 | - PrvListenThread 91 | - PrvLockBus 92 | - PrvPut 93 | - PrvReleaseBus 94 | - SpipClearSignal 95 | - SpipClose 96 | - SpipGetWaitFd 97 | - SpipInit 98 | - SpipSignal 99 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # [open]lipc - configure.ac 2 | # Copyright (c) 2016 Arkadiusz Bokowy 3 | 4 | AC_INIT([openlipc], [0.1.0], [arkadiusz.bokowy@gmail.com]) 5 | AC_CONFIG_HEADERS([config.h]) 6 | AM_INIT_AUTOMAKE([foreign -Wall -Werror]) 7 | 8 | AC_PROG_CC 9 | AM_PROG_CC_C_O 10 | 11 | 12 | AC_ARG_VAR([KINDLE_ROOTDIR], [directory containing Kindle root tree]) 13 | AC_ARG_ENABLE([kindle-env], 14 | [AS_HELP_STRING([--enable-kindle-env[[=DIR]]], [use Kindle environment])], [ 15 | if test "x$enableval" != "xno"; then enable_kindle_env=yes; fi 16 | if test "x$enableval" != "xno" -a "x$enableval" != "xyes"; then 17 | AC_SUBST([KINDLE_ROOTDIR], [$enableval]) 18 | fi 19 | ]) 20 | AM_CONDITIONAL([ENABLE_KINDLE_ENV], [test "x$enable_kindle_env" = "xyes"]) 21 | AM_COND_IF([ENABLE_KINDLE_ENV], [ 22 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifndef __arm__ 23 | error: Not an ARM compiler! 24 | #endif]])], [], 25 | [AC_MSG_FAILURE([ARM-compatible compiler is required])]) 26 | if test "x$KINDLE_ROOTDIR" = "x"; then 27 | AC_MSG_WARN([Kindle environment enabled, but Kindle root tree location not given!]) 28 | AC_MSG_WARN([Either set the KINDLE_ROOTDIR environmental variable or set the root]) 29 | AC_MSG_WARN([tree location with the --enable-kindle-env option.]) 30 | fi 31 | ]) 32 | 33 | 34 | AC_ARG_WITH([lipc-prop], 35 | [AS_HELP_STRING([--without-lipc-prop], [omit lipc-get/set-prop replacements])], 36 | [], [with_lipc_prop=yes]) 37 | AM_CONDITIONAL([WITH_LIPC_PROP], [test "x$with_lipc_prop" = "xyes"]) 38 | 39 | AC_ARG_WITH([lipc-probe], 40 | [AS_HELP_STRING([--without-lipc-probe], [omit lipc-probe replacement])], 41 | [], [with_lipc_probe=yes]) 42 | AM_CONDITIONAL([WITH_LIPC_PROBE], [test "x$with_lipc_probe" = "xyes"]) 43 | AM_COND_IF([WITH_LIPC_PROBE], [ 44 | PKG_CHECK_MODULES([GLIB20], [glib-2.0]) 45 | PKG_CHECK_MODULES([GIO20], [gio-2.0]) 46 | ]) 47 | 48 | 49 | AC_CONFIG_FILES([Makefile src/Makefile test/Makefile]) 50 | AC_OUTPUT 51 | -------------------------------------------------------------------------------- /include/openlipc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file openlipc.h 3 | * @brief Open-source LIPC header file. 4 | * 5 | * This file is a part of [open]lipc. 6 | * 7 | * @mainpage 8 | * LIPC is a proprietary (developed by the Amazon) IPC library based on D-Bus. 9 | * It links internal Kindle components together. Via this library one is able 10 | * to expose application properties (setters and getters), access properties 11 | * of other applications and listen for or emit events. 12 | * 13 | * The [open]lipc project is a reverse-engineered header file for this library. 14 | * It can be used to build native applications for Kindle device with an easy 15 | * and simple access to the core system components exposed via the LIPC. 16 | * 17 | * The basic usage of this header file might be as follows: 18 | * @code 19 | * #include 20 | * #include 21 | * 22 | * int main(void) { 23 | * 24 | * LIPC *lipc; 25 | * char *status; 26 | * 27 | * if ((lipc = LipcOpenNoName()) == NULL) 28 | * return 1; 29 | * 30 | * if (LipcGetStringProperty(lipc, "com.lab126.powerd", "status", &status) == LIPC_OK) { 31 | * puts(status); 32 | * LipcFreeString(status); 33 | * } 34 | * 35 | * LipcClose(lipc); 36 | * return 0; 37 | * } 38 | * @endcode 39 | * 40 | * @copyright 41 | * This project is licensed under the terms of the MIT license. 42 | * 43 | * @note 44 | * The [open]lipc header file is based on the reverse-engineered proprietary 45 | * library, which is a part of the Kindle firmware. The LIPC library itself is 46 | * copyrighted under the terms of the Amazon Technologies, Inc. 47 | * 48 | */ 49 | 50 | #ifndef OPENLIPC_H 51 | #define OPENLIPC_H 52 | 53 | #include 54 | #include 55 | 56 | #ifdef __cplusplus 57 | extern "C" { 58 | #endif 59 | 60 | /** 61 | * @defgroup lipc-init Initialization 62 | * @brief Library initialization and error handling. 63 | * @{ */ 64 | 65 | /** LIPC library handler. */ 66 | typedef void LIPC; 67 | 68 | /** 69 | * Status codes returned by all sorts of LIPC library functions. 70 | * 71 | * @warning 72 | * This list was obtained from the LipcGetErrorString() function and may 73 | * be not complete - be prepared for other values as well. */ 74 | typedef enum { 75 | LIPC_OK = 0, 76 | LIPC_ERROR_UNKNOWN, /* 1 */ 77 | LIPC_ERROR_INTERNAL, /* 2 */ 78 | LIPC_ERROR_NO_SUCH_SOURCE, /* 3 */ 79 | LIPC_ERROR_OPERATION_NOT_SUPPORTED, /* 4 */ 80 | LIPC_ERROR_OUT_OF_MEMORY, /* 5 */ 81 | LIPC_ERROR_SUBSCRIPTION_FAILED, /* 6 */ 82 | LIPC_ERROR_NO_SUCH_PARAM, /* 7 */ 83 | LIPC_ERROR_NO_SUCH_PROPERTY, /* 8 */ 84 | LIPC_ERROR_ACCESS_NOT_ALLOWED, /* 9 */ 85 | LIPC_ERROR_BUFFER_TOO_SMALL, /* 10 */ 86 | LIPC_ERROR_INVALID_HANDLE, /* 11 */ 87 | LIPC_ERROR_INVALID_ARG, /* 12 */ 88 | LIPC_ERROR_OPERATION_NOT_ALLOWED, /* 13 */ 89 | LIPC_ERROR_PARAMS_SIZE_EXCEEDED, /* 14 */ 90 | LIPC_ERROR_TIMED_OUT, /* 15 */ 91 | LIPC_ERROR_SERVICE_NAME_TOO_LONG, /* 16 */ 92 | LIPC_ERROR_DUPLICATE_SERVICE_NAME, /* 17 */ 93 | LIPC_ERROR_INIT_DBUS, /* 18 */ 94 | LIPC_PROP_ERROR_INVALID_STATE = 0x100, 95 | LIPC_PROP_ERROR_NOT_INITIALIZED = 0x101, 96 | LIPC_PROP_ERROR_INTERNAL = 0x102, 97 | } LIPCcode; 98 | 99 | /** 100 | * Initialize LIPC library without registering a new service. 101 | * 102 | * @return On success the LIPC library handler is returned, which should be 103 | * closed with the LipcClose(). Upon error this function returns NULL. */ 104 | LIPC *LipcOpenNoName(void); 105 | 106 | /** 107 | * Initialize LIPC library and register a new service. 108 | * 109 | * @param service The service name which should be registered. The name has 110 | * to be a fully qualified dot-separated identifier, e.g. "org.MyService". 111 | * @return On success the LIPC library handler is returned, which should be 112 | * closed with the LipcClose(). Upon error this function returns NULL. */ 113 | LIPC *LipcOpen(const char *service); 114 | 115 | /** 116 | * Initialize LIPC library and register a new service. 117 | * 118 | * This function is an extended version of the LipcOpen(). 119 | * 120 | * @param service The service name which should be registered. The name has 121 | * to be a fully qualified dot-separated identifier, e.g. "org.MyService". 122 | * @param code If not NULL, the status code will be stored in this argument. 123 | * @return On success the LIPC library handler is returned, which should be 124 | * closed with the LipcClose(). Upon error this function returns NULL. */ 125 | LIPC *LipcOpenEx(const char *service, LIPCcode *code); 126 | 127 | /** 128 | * Close the LIPC handler and release all associated resources. 129 | * 130 | * @param lipc LIPC library handler. */ 131 | void LipcClose(LIPC *lipc); 132 | 133 | /** 134 | * Get the service name associated with the LIPC handler. 135 | * 136 | * @param lipc LIPC library handler. 137 | * @return The service name which was registered during LIPC opening or NULL 138 | * if the handler was obtained by the call to the LipcOpenNoName(). */ 139 | const char *LipcGetServiceName(LIPC *lipc); 140 | 141 | /** 142 | * Get status code in the string format. 143 | * 144 | * @param code The status code. 145 | * @return String with the human-readable status. */ 146 | const char *LipcGetErrorString(LIPCcode code); 147 | 148 | /** @} 149 | ***/ 150 | 151 | /** 152 | * @defgroup lipc-hasharray HashArray 153 | * @brief Hash-array data structure. 154 | * @{ */ 155 | 156 | /** LIPC hash-array handler. */ 157 | typedef void LIPCha; 158 | 159 | /** 160 | * Possible data types, which can be stored in the value of the hash component 161 | * in the hash-array data structure. */ 162 | typedef enum { 163 | LIPC_HASHARRAY_INT = 0, 164 | LIPC_HASHARRAY_STRING = 1, 165 | LIPC_HASHARRAY_BLOB = 2, 166 | } LIPCHasharrayType; 167 | 168 | /** 169 | * Initialize new hash-array data structure. 170 | * 171 | * @param lipc LIPC library handler. 172 | * @return The LIPC hash-array handler or NULL upon error. */ 173 | LIPCha *LipcHasharrayNew(LIPC *lipc); 174 | 175 | /** 176 | * Free resources associated with the hash-array handler. 177 | * 178 | * @param ha The LIPC hash-array handler. 179 | * @param destroy If TRUE, the underlying shared memory segment will be marked 180 | * to be destroyed. 181 | * @return The status code. */ 182 | LIPCcode LipcHasharrayFree(LIPCha *ha, int destroy); 183 | 184 | /** 185 | * Free resources associated with the hash-array handler. 186 | * 187 | * This function is an equivalent of calling the LipcHasharrayFree() function 188 | * with the destroy parameter set to TRUE. 189 | * 190 | * @param ha The LIPC hash-array handler. 191 | * @return The status code. */ 192 | LIPCcode LipcHasharrayDestroy(LIPCha *ha); 193 | 194 | /** 195 | * Get the number of elements in the array component of the hash-array data 196 | * structure. 197 | * 198 | * @param ha The LIPC hash-array handler. 199 | * @return The array size or -1 upon error. */ 200 | int LipcHasharrayGetHashCount(LIPCha *ha); 201 | 202 | /** 203 | * Append new hash map to the hash-array structure. 204 | * 205 | * @param ha The LIPC hash-array handler. 206 | * @param index The address where the index of newly added hash map (hence, 207 | * the size of the array) will be stored. 208 | * @return The status code. */ 209 | LIPCcode LipcHasharrayAddHash(LIPCha *ha, size_t *index); 210 | 211 | /** 212 | * Get keys stored in the hash map of the hash-array data structure. 213 | * 214 | * In order to determine the number of keys at the given index, one should 215 | * call this function with the count parameter initialized to 0. The number 216 | * of available keys will be returned back in this parameter - in fact the 217 | * count parameter is always modified, and the number of keys is returned in 218 | * it (be careful when reusing this variable for iteration over keys array). 219 | * 220 | * @param ha The LIPC hash-array handler. 221 | * @param index The 0-based index in the array. 222 | * @param keys The array which can store up to the count number of string 223 | * pointers - keys. 224 | * @param count The address where the number of keys to fetch is given. 225 | * @return The status code. */ 226 | LIPCcode LipcHasharrayKeys(LIPCha *ha, int index, const char *keys[], 227 | size_t *count); 228 | 229 | /** 230 | * Get the data type stored in the hash map of the hash-array data structure. 231 | * 232 | * @param ha The LIPC hash-array handler. 233 | * @param index The 0-based index in the array. 234 | * @param key The key name to check. 235 | * @param type The address where the data type will be stored. 236 | * @param size The address where the size of the value will be stored. 237 | * @return The status code. */ 238 | LIPCcode LipcHasharrayCheckKey(LIPCha *ha, int index, const char *key, 239 | LIPCHasharrayType *type, size_t *size); 240 | 241 | /** 242 | * Get the integer value form the hash map of the hash-array data structure. 243 | * 244 | * @param ha The LIPC hash-array handler. 245 | * @param index The 0-based index in the array. 246 | * @param key The key name to get. 247 | * @param value The address where the integer value will be stored. 248 | * @return The status code. */ 249 | LIPCcode LipcHasharrayGetInt(LIPCha *ha, int index, const char *key, 250 | int *value); 251 | 252 | /** 253 | * Put the integer value into the hash map of the hash-array data structure. 254 | * 255 | * @param ha The LIPC hash-array handler. 256 | * @param index The 0-based index in the array. 257 | * @param key The key name to set. 258 | * @param value The value to set. 259 | * @return The status code. */ 260 | LIPCcode LipcHasharrayPutInt(LIPCha *ha, int index, const char *key, 261 | int value); 262 | 263 | /** 264 | * Get the string value form the hash map of the hash-array data structure. 265 | * 266 | * @param ha The LIPC hash-array handler. 267 | * @param index The 0-based index in the array. 268 | * @param key The key name to get. 269 | * @param value The address where the pointer to the string will be stored. 270 | * @return The status code. */ 271 | LIPCcode LipcHasharrayGetString(LIPCha *ha, int index, const char *key, 272 | char **value); 273 | 274 | /** 275 | * Put the string value into the hash map of the hash-array data structure. 276 | * 277 | * @param ha The LIPC hash-array handler. 278 | * @param index The 0-based index in the array. 279 | * @param key The key name to set. 280 | * @param value The value to set. 281 | * @return The status code. */ 282 | LIPCcode LipcHasharrayPutString(LIPCha *ha, int index, const char *key, 283 | const char *value); 284 | 285 | /** 286 | * Get the blob data from the hash map of the hash-array data structure. 287 | * 288 | * @param ha The LIPC hash-array handler. 289 | * @param index The 0-based index in the array. 290 | * @param key The key name to get. 291 | * @param data The address where the pointer to the data will be stored. 292 | * @param size The address where the size of the data will be stored. 293 | * @return The status code. */ 294 | LIPCcode LipcHasharrayGetBlob(LIPCha *ha, int index, const char *key, 295 | unsigned char *data[], size_t *size); 296 | 297 | /** 298 | * Put the blob data into the hash map of the hash-array data structure. 299 | * 300 | * @param ha The LIPC hash-array handler. 301 | * @param index The 0-based index in the array. 302 | * @param key The key name to set. 303 | * @param data The data to set. 304 | * @param size The size of the data. 305 | * @return The status code. */ 306 | LIPCcode LipcHasharrayPutBlob(LIPCha *ha, int index, const char *key, 307 | const unsigned char *data, size_t size); 308 | 309 | /** 310 | * Copy a hash-array data structure. 311 | * 312 | * The destination hash-array structure handler has to be initialized with the 313 | * LipcHasharrayNew() function. 314 | * 315 | * @param dest The destination hash-array handler. 316 | * @param src The source hash-array handler. 317 | * @return The status code. */ 318 | LIPCcode LipcHasharrayCopy(LIPCha *dest, const LIPCha *src); 319 | 320 | /** 321 | * Copy a single hash map of the hash-array data structure. 322 | * 323 | * The destination hash-array structure handler has to be initialized with the 324 | * LipcHasharrayNew() function. 325 | * 326 | * @param dest The destination hash-array handler. 327 | * @param dest_index The index in the destination hash-array structure, where 328 | * the copied hash map will be placed. 329 | * @param src The source hash-array handler. 330 | * @param src_index The index within the source hash-array structure, from 331 | * where the hash map is copied. 332 | * @return The status code. */ 333 | LIPCcode LipcHasharrayCopyHash(LIPCha *dest, int dest_index, 334 | const LIPCha *src, int src_index); 335 | 336 | /** 337 | * Clone a hash-array data structure. 338 | * 339 | * This function is (almost) an equivalent of calling the LipcHasharrayCopy() 340 | * function using a newly initialized hash-array handler. However, using this 341 | * function ensures, that the internal hash-array key and few other internal 342 | * fields are copied too. The exact meaning of these fields is unknown. 343 | * 344 | * @param ha The hash-array handler to the structure which should be cloned. 345 | * @return On success the LIPC hash-array handler to the new data structure 346 | * is returned. Upon error this function returns NULL. */ 347 | LIPCha *LipcHasharrayClone(const LIPCha *ha); 348 | 349 | /** 350 | * Save hash-array memory into the given file descriptor. 351 | * 352 | * @param ha The hash-array handler. 353 | * @param fd Opened file descriptor with the write permission. 354 | * @return The status code. */ 355 | LIPCcode LipcHasharraySave(const LIPCha *ha, int fd); 356 | 357 | /** 358 | * Restore hash-array form the memory read from the given file descriptor. 359 | * 360 | * @param lipc LIPC library handler. 361 | * @param fd Opened file descriptor with the read permission. 362 | * @return On success the LIPC hash-array handler to the restored data 363 | * structure is returned. Upon error this function returns NULL. */ 364 | LIPCha *LipcHasharrayRestore(LIPC *lipc, int fd); 365 | 366 | /** 367 | * Get string representation of the given hash-array. 368 | * 369 | * In order to determine the number of bytes required to store the string 370 | * representation of the given hash-array data structure, one should call this 371 | * function with the size parameter initialized to 0. The number of required 372 | * bytes will be returned back in this parameter - in fact the size parameter 373 | * is always modified, and the number of required bytes is returned in it (be 374 | * careful when reusing this variable). 375 | * 376 | * @param ha The hash-array handler. 377 | * @param str The pointer to the address, where the hash-array string 378 | * representation will be stored. 379 | * @param size The pointer to the address, where the size of the str buffer 380 | * is passed. On return, the number of actually used bytes will be stored 381 | * at this address. 382 | * @return The status code. */ 383 | LIPCcode LipcHasharrayToString(const LIPCha *ha, char *str, size_t *size); 384 | 385 | /** @} 386 | ***/ 387 | 388 | /** 389 | * @defgroup lipc-property Properties 390 | * @brief Accessing and exposing properties. 391 | * @{ */ 392 | 393 | /** 394 | * Get property access timeout. 395 | * 396 | * @note 397 | * The timeout value can be set via the file "/var/local/system/lipctimeout", 398 | * otherwise it is set to the default 10000 ms. 399 | * 400 | * @param lipc LIPC library handler. 401 | * @return The timeout value in milliseconds. */ 402 | int LipcGetPropAccessTimeout(LIPC *lipc); 403 | 404 | /** 405 | * Get the value of the integer property. 406 | * 407 | * @param lipc LIPC library handler. 408 | * @param service The service name. 409 | * @param property The property name. 410 | * @param value The address where the integer value will be stored. 411 | * @return The status code. */ 412 | LIPCcode LipcGetIntProperty(LIPC *lipc, const char *service, 413 | const char *property, int *value); 414 | 415 | /** 416 | * Set the value of the integer property. 417 | * 418 | * @param lipc LIPC library handler. 419 | * @param service The service name. 420 | * @param property The property name. 421 | * @param value The new value to set. 422 | * @return The status code. */ 423 | LIPCcode LipcSetIntProperty(LIPC *lipc, const char *service, 424 | const char *property, int value); 425 | 426 | /** 427 | * Get the value of the string property. 428 | * 429 | * The memory for the returned string is allocated internally by the library 430 | * and should be freed with the LipcFreeString(). 431 | * 432 | * @param lipc LIPC library handler. 433 | * @param service The service name. 434 | * @param property The property name. 435 | * @param value The address where the pointer to the string will be stored. 436 | * @return The status code. */ 437 | LIPCcode LipcGetStringProperty(LIPC *lipc, const char *service, 438 | const char *property, char **value); 439 | 440 | /** 441 | * Set the value of the string property. 442 | * 443 | * @param lipc LIPC library handler. 444 | * @param service The service name. 445 | * @param property The property name. 446 | * @param value The new value to set. 447 | * @return The status code. */ 448 | LIPCcode LipcSetStringProperty(LIPC *lipc, const char *service, 449 | const char *property, const char *value); 450 | 451 | /** 452 | * Access the value of the hash-array property. 453 | * 454 | * @param lipc LIPC library handler. 455 | * @param service The service name. 456 | * @param property The property name. 457 | * @param ha An input LIPC hash-array handler or NULL if there is no input. 458 | * @param ha_out The pointer to the address, where the output hash-array 459 | * handler will be stored. If the output value is not desired, one can 460 | * pass NULL value in this parameter. 461 | * @return The status code. */ 462 | LIPCcode LipcAccessHasharrayProperty(LIPC *lipc, const char *service, 463 | const char *property, const LIPCha *ha, 464 | LIPCha **ha_out); 465 | 466 | /** 467 | * Convenience macro for getting all properties of given service. 468 | * 469 | * The list of properties is formated as a space-delimited string, where every 470 | * element is in the format as follows: " ". Note, 471 | * that at the end of the string, there is always a hanging space character. 472 | * 473 | * The access mode of the property can be either read-only: r, write-only: w, 474 | * or both: rw. 475 | * 476 | * @param lipc LIPC library handler. 477 | * @param service The service name. 478 | * @param value The address where the pointer to the string will stored. 479 | * @return The status code. */ 480 | #define LipcGetProperties(lipc, service, value) \ 481 | LipcGetStringProperty(lipc, service, "_properties", value) 482 | 483 | /** 484 | * Free memory allocated by the LIPC. 485 | * 486 | * @param string The string pointer. */ 487 | void LipcFreeString(char *string); 488 | 489 | /** 490 | * Property getter/setter callback function. 491 | * 492 | * This callback function can be used either for getting properties or for 493 | * setting ones. However, there is a slight difference in both actions. Also, 494 | * there is a difference when the callback function is called for getting a 495 | * string, and when it is called for getting an integer. 496 | * 497 | * When the getter is called for the integer property, one has to set the 498 | * address pointed by the *value to the desired integer value. 499 | * 500 | * When the getter is called for the string property, the buffer pointed by 501 | * the *value is preallocated to the initial size. This size is available in 502 | * the *data parameter. If the buffer is too small for storing desired string 503 | * value, one should return the LIPC_ERROR_BUFFER_TOO_SMALL code and pass the 504 | * required buffer size in the *data argument. In such a case, the callback 505 | * function will be called again with the requested buffer size. 506 | * 507 | * When the setter is called, the value parameter contains the integer value 508 | * itself or it points to the memory buffer, respectively for the integer 509 | * property or for the string property. 510 | * 511 | * For convenience, one can use one of the helper macros (LIPC_GETTER_VTOI(), 512 | * LIPC_SETTER_VTOI(), LIPC_GETTER_VTOS() or LIPC_SETTER_VTOS()) for casting 513 | * the value parameter into the proper type based on the callback type. 514 | * 515 | * In all cases, with the exception of the string property getter, the data 516 | * parameter will contain the value passed during the property registration. 517 | * 518 | * The return value of the callback function will be used as a return value 519 | * for the caller, e.g. LipcGetIntProperty(). One exception from this rule is 520 | * a getter for a string property, where the LIPC_ERROR_BUFFER_TOO_SMALL code 521 | * is used internally by the LIPC library. 522 | * 523 | * @param lipc LIPC library handler. 524 | * @param property The property name. 525 | * @param value Pointer to the memory area for a value storage. 526 | * @param data Data passed during property registration. 527 | * @return The status code. */ 528 | typedef LIPCcode (*LipcPropCallback)(LIPC *lipc, const char *property, 529 | void *value, void *data); 530 | 531 | /** Cast the value parameter of the getter callback into the integer type. */ 532 | #define LIPC_GETTER_VTOI(value) (*(int *)(value)) 533 | /** Cast the value parameter of the setter callback into the integer type. */ 534 | #define LIPC_SETTER_VTOI(value) ((long int)(value)) 535 | /** Cast the value parameter of the getter callback into the char * type. */ 536 | #define LIPC_GETTER_VTOS(value) ((char *)(value)) 537 | /** Cast the value parameter of the setter callback into the char * type. */ 538 | #define LIPC_SETTER_VTOS(value) ((char *)(value)) 539 | 540 | /** 541 | * Register new integer property. 542 | * 543 | * The access mode of the property is determined by the presence of the getter 544 | * and/or the setter callback function. Passing NULL value in the getter and 545 | * the setter parameters will make the property read-only, however it will not 546 | * be possible to retrieve any value, so it is pointless to do so. 547 | * 548 | * @param lipc LIPC library handler. 549 | * @param property The property name. 550 | * @param getter Getter callback if property is readable. 551 | * @param setter Setter callback if property is writable. 552 | * @param data Data pointer passed to the callback function. 553 | * @return The status code. */ 554 | LIPCcode LipcRegisterIntProperty(LIPC *lipc, const char *property, 555 | LipcPropCallback getter, 556 | LipcPropCallback setter, 557 | void *data); 558 | 559 | /** 560 | * Register new string property. 561 | * 562 | * For the information about the property access mode, see the documentation 563 | * of the LipcRegisterIntProperty(). 564 | * 565 | * @param lipc LIPC library handler. 566 | * @param property The property name. 567 | * @param getter Getter callback if property is readable. 568 | * @param setter Setter callback if property is writable. 569 | * @param data Data pointer passed to the callback function. 570 | * @return The status code. */ 571 | LIPCcode LipcRegisterStringProperty(LIPC *lipc, const char *property, 572 | LipcPropCallback getter, 573 | LipcPropCallback setter, 574 | void *data); 575 | 576 | /** 577 | * Register new hash-array property. 578 | * 579 | * @param lipc LIPC library handler. 580 | * @param property The property name. 581 | * @param callback Getter and setter callback function. 582 | * @param data Data pointer passed to the callback function. 583 | * @return The status code. */ 584 | LIPCcode LipcRegisterHasharrayProperty(LIPC *lipc, const char *property, 585 | LipcPropCallback callback, 586 | void *data); 587 | 588 | /** 589 | * Unregister property. 590 | * 591 | * If the data parameter is not NULL, the address of the data pointer passed 592 | * during the property registration will be stored in the address pointed by 593 | * the *data. 594 | * 595 | * @param lipc LIPC library handler. 596 | * @param property The property name. 597 | * @param data Address where the data pointer is returned. 598 | * @return The status code. */ 599 | LIPCcode LipcUnregisterProperty(LIPC *lipc, const char *property, void **data); 600 | 601 | /** @} 602 | ***/ 603 | 604 | /** 605 | * @defgroup lipc-event Events 606 | * @brief Listening for and emitting events. 607 | * @{ */ 608 | 609 | /** LIPC event handler. */ 610 | typedef void LIPCevent; 611 | 612 | /** 613 | * Create a new event object. 614 | * 615 | * In order to use this function the LIPC handler has to be opened with the 616 | * service name given using LipcOpen() or LipcOpenEx(). 617 | * 618 | * @param lipc LIPC library handler. 619 | * @param name The event name. 620 | * @return On success the LIPCevent handler is returned, which should be freed 621 | * with the LipcEventFree(). Upon error this function returns NULL. */ 622 | LIPCevent *LipcNewEvent(LIPC *lipc, const char *name); 623 | 624 | /** 625 | * Free memory allocated by the LIPC. 626 | * 627 | * @param event LIPC event handler. */ 628 | void LipcEventFree(LIPCevent *event); 629 | 630 | /** 631 | * Send event object. 632 | * 633 | * @param lipc LIPC library handler. 634 | * @param event LIPC event handler. 635 | * @return The status code. */ 636 | LIPCcode LipcSendEvent(LIPC *lipc, LIPCevent *event); 637 | 638 | /** 639 | * Create and send event. 640 | * 641 | * This function is an equivalent of using LipcNewEvent(), LipcSendEvent() and 642 | * LipcEventFree() all together. If you want to send a simple event object - 643 | * one without any parameters - use this function. 644 | * 645 | * @param lipc LIPC library handler. 646 | * @param name The event name. 647 | * @return The status code. */ 648 | LIPCcode LipcCreateAndSendEvent(LIPC *lipc, const char *name); 649 | 650 | /** 651 | * Create and send event. 652 | * 653 | * This function creates an event object and sets its parameters according to 654 | * the format string. This function takes variable number of arguments. 655 | * 656 | * LIPC supports two kinds of event parameters: integers and strings. It is 657 | * possible to specify both of these types via the format string in the same 658 | * way the printf() function family does. The format string can contain any 659 | * number of "%d" or/and "%s" conversion specifiers. It is also possible to 660 | * pass an empty string in the format argument, which will be an equivalent 661 | * of calling the LipcCreateAndSendEvent(). 662 | * 663 | * The format string also supports the ".0" precision modifier. However, its 664 | * purpose is yet to be discovered. 665 | * 666 | * @param lipc LIPC library handler. 667 | * @param name The event name. 668 | * @param format The format string. 669 | * @param ... Variable list of parameters. 670 | * @return The status code. */ 671 | LIPCcode LipcCreateAndSendEventWithParameters(LIPC *lipc, const char *name, 672 | const char *format, ...); 673 | 674 | /** 675 | * Create and send event. 676 | * 677 | * This function creates an event object and sets its parameters according to 678 | * the format string. Parameter values should be passed as a variable argument 679 | * list. For the list of all supported formats, see the documentation of the 680 | * LipcCreateAndSendEventWithParameters() function. 681 | * 682 | * @param lipc LIPC library handler. 683 | * @param name The event name. 684 | * @param format The format string. 685 | * @param ap Variable argument list. 686 | * @return The status code. */ 687 | LIPCcode LipcCreateAndSendEventWithVAListParameters(LIPC *lipc, 688 | const char *name, 689 | const char *format, 690 | va_list ap); 691 | 692 | /** 693 | * Get the source name associated with the event. 694 | * 695 | * @param event LIPC event handler. 696 | * @return The source name from where the event originates. */ 697 | const char *LipcGetEventSource(LIPCevent *event); 698 | 699 | /** 700 | * Get the name of the event. 701 | * 702 | * @param event LIPC event handler. 703 | * @return The event name. */ 704 | const char *LipcGetEventName(LIPCevent *event); 705 | 706 | /** 707 | * Get the integer parameter from the event. 708 | * 709 | * @param event LIPC event handler. 710 | * @param value The address where the integer value will be stored. 711 | * @return The status code. */ 712 | LIPCcode LipcGetIntParam(LIPCevent *event, int *value); 713 | 714 | /** 715 | * Add the integer parameter to the event. 716 | * 717 | * @param event LIPC event handler. 718 | * @param value The new value to add. 719 | * @return The status code. */ 720 | LIPCcode LipcAddIntParam(LIPCevent *event, int value); 721 | 722 | /** 723 | * Get the string parameter from the event. 724 | * 725 | * @note 726 | * The obtained memory pointer should not be passed to the LipcFreeString() 727 | * function. It seems, that the memory is managed internally by the library. 728 | * 729 | * @param event LIPC event handler. 730 | * @param value The address where the pointer to the string will be stored. 731 | * @return The status code. */ 732 | LIPCcode LipcGetStringParam(LIPCevent *event, char **value); 733 | 734 | /** 735 | * Add the string parameter to the event. 736 | * 737 | * @param event LIPC event handler. 738 | * @param value The new value to add. 739 | * @return The status code. */ 740 | LIPCcode LipcAddStringParam(LIPCevent *event, const char *value); 741 | 742 | /** 743 | * Rewind parameters of the event. 744 | * 745 | * @param event LIPC event handler. 746 | * @return The status code. */ 747 | LIPCcode LipcRewindParams(LIPCevent *event); 748 | 749 | /** 750 | * Event dispatching callback function. 751 | * 752 | * @param lipc LIPC library handler. 753 | * @param name The event name. 754 | * @param event The LIPC event handler. 755 | * @param data Data pointer passed during subscription. 756 | * @return The status code. */ 757 | typedef LIPCcode (*LipcEventCallback)(LIPC *lipc, const char *name, 758 | LIPCevent *event, void *data); 759 | 760 | /** 761 | * Set default event callback function. 762 | * 763 | * The callback function will be called when one uses the LipcSubscribe() 764 | * subscription mechanism. Note, that it is not possible to pass user-defined 765 | * data via this approach - if one wants to pass extra data to the callback 766 | * function, one should use the LipcSubscribeExt() instead. 767 | * 768 | * @param lipc LIPC library handler. 769 | * @param callback Event dispatching callback function. 770 | * @return The status code. */ 771 | LIPCcode LipcSetEventCallback(LIPC *lipc, LipcEventCallback callback); 772 | 773 | /** 774 | * Subscribe for all events emitted by the service. 775 | * 776 | * In order to receive event notifications, one has to set default callback 777 | * function using the LipcSetEventCallback() function. Using them both, is an 778 | * equivalent of using the extended version with parameters set as follows: 779 | * LipcSubscribeExt(lipc, service, NULL, callback, NULL) 780 | * 781 | * @param lipc LIPC library handler. 782 | * @param service The service name. 783 | * @return The status code. */ 784 | LIPCcode LipcSubscribe(LIPC *lipc, const char *service); 785 | 786 | /** 787 | * Subscribe for events emitted by the service. 788 | * 789 | * This function is an extended version of the LipcSubscribe(), which allows 790 | * to set the event name for which one wants to subscribe and the user-defined 791 | * data passed to the callback function. Passing NULL instead of the event 792 | * name will subscribe for all events. 793 | * 794 | * @param lipc LIPC library handler. 795 | * @param service The service name. 796 | * @param name The event name. 797 | * @param callback Event dispatching callback function. 798 | * @param data Data pointer passed to the callback function. 799 | * @return The status code. */ 800 | LIPCcode LipcSubscribeExt(LIPC *lipc, const char *service, const char *name, 801 | LipcEventCallback callback, void *data); 802 | 803 | /** 804 | * Unsubscribe from event or events. 805 | * 806 | * If the event name is NULL, this function will unsubscribe from events 807 | * delivered to the callback set with the LipcSetEventCallback(). 808 | * 809 | * @param lipc LIPC library handler. 810 | * @param service The service name. 811 | * @param name The event name or NULL. 812 | * @param data Address where the data pointer is returned or NULL. 813 | * @return The status code. */ 814 | LIPCcode LipcUnsubscribeExt(LIPC *lipc, const char *service, 815 | const char *name, void **data); 816 | 817 | /** @} 818 | ***/ 819 | 820 | /** 821 | * @defgroup lipc-log Logging 822 | * @brief LIPC internal logging. 823 | * @{ */ 824 | 825 | /** 826 | * Log debug messages. 827 | * 828 | * LIPC defines 8 levels of debug messages. Via this macro one can select the 829 | * level which should be logged. Valid values are from 1 to 8. */ 830 | #define LAB126_LOG_DEBUG (n) ((1 << ((n) - 1)) << 8) 831 | #define LAB126_LOG_INFO (0x0080 << 16) 832 | #define LAB126_LOG_WARNING (0x0100 << 16) 833 | #define LAB126_LOG_ERROR (0x0200 << 16) 834 | #define LAB126_LOG_CRITICAL (0x0400 << 16) 835 | #define LAB126_LOG_DEBUG_ALL 0x0000FF00 836 | #define LAB126_LOG_ALL 0xFFFFFF00 837 | 838 | /** Global logging mask. */ 839 | extern int g_lab126_log_mask; 840 | 841 | /** Set the LIPC internal logging mask. 842 | * 843 | * The logging mask parameter should be the logical OR of the logging flags 844 | * (LAB126_LOG_* definitions). The current state of the logging mask can be 845 | * accessed via the g_lab126_log_mask global variable. 846 | * 847 | * @param mask The logging mask. */ 848 | void LipcSetLlog(int mask); 849 | 850 | /** @} 851 | ***/ 852 | 853 | #ifdef __cplusplus 854 | } 855 | #endif 856 | 857 | #endif /* OPENLIPC_H */ 858 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | # [open]lipc - Makefile.am 2 | # Copyright (c) 2016 Arkadiusz Bokowy 3 | 4 | AM_CFLAGS = -I$(top_srcdir)/include 5 | LDADD = -llipc 6 | 7 | bin_PROGRAMS = 8 | 9 | if WITH_LIPC_PROP 10 | bin_PROGRAMS += lipc-get-prop lipc-set-prop 11 | endif 12 | 13 | if WITH_LIPC_PROBE 14 | bin_PROGRAMS += lipc-probe 15 | lipc_probe_CFLAGS = $(AM_CFLAGS) @GLIB20_CFLAGS@ @GIO20_CFLAGS@ 16 | lipc_probe_LDADD = $(LDADD) @GLIB20_LIBS@ @GIO20_LIBS@ 17 | endif 18 | 19 | if ENABLE_KINDLE_ENV 20 | AM_LDFLAGS = \ 21 | -L$(KINDLE_ROOTDIR)/lib \ 22 | -L$(KINDLE_ROOTDIR)/usr/lib \ 23 | -Wl,-rpath=$(KINDLE_ROOTDIR)/lib \ 24 | -Wl,-rpath=$(KINDLE_ROOTDIR)/usr/lib 25 | endif 26 | -------------------------------------------------------------------------------- /src/lipc-get-prop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * [open]lipc - lipc-get-prop.c 3 | * Copyright (c) 2016 Arkadiusz Bokowy 4 | * 5 | * This file is a part of openlipc. 6 | * 7 | * This project is licensed under the terms of the MIT license. 8 | * 9 | * This source code is based on the reverse-engineered application, which is 10 | * a part of the Kindle firmware. The original lipc-get-prop application is 11 | * copyrighted under the terms of the Amazon Technologies, Inc. 12 | * 13 | */ 14 | 15 | #include "openlipc.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | enum property { 24 | PROPERTY_INT, 25 | PROPERTY_STR, 26 | PROPERTY_HAS, 27 | }; 28 | 29 | int main(int argc, char *argv[]) { 30 | 31 | int opt; 32 | 33 | enum property kind = PROPERTY_INT; 34 | int end_nl = 1; 35 | int quiet = 0; 36 | 37 | while ((opt = getopt(argc, argv, "hisjeq")) != -1) 38 | switch (opt) { 39 | case 'h': 40 | printf("usage: %s [-isjeq] \n\n" 41 | " publisher - the unique name of the publisher\n" 42 | " property - the name of the property to get\n" 43 | "\n" 44 | "options:\n" 45 | " -i\tpublisher published an integer property\n" 46 | " -s\tpublisher published a string property\n" 47 | " -j\tpublisher published a hash-array property\n" 48 | " -e\tdo not print new line at the end\n" 49 | " -q\tdo not print error message\n", 50 | argv[0]); 51 | return EXIT_SUCCESS; 52 | 53 | case 'i': 54 | kind = PROPERTY_INT; 55 | break; 56 | case 's': 57 | kind = PROPERTY_STR; 58 | break; 59 | case 'j': 60 | kind = PROPERTY_HAS; 61 | break; 62 | case 'e': 63 | end_nl = 0; 64 | break; 65 | case 'q': 66 | quiet = 1; 67 | break; 68 | 69 | default: 70 | usage: 71 | fprintf(stderr, "Try '%s -h' for more information.\n", argv[0]); 72 | return EXIT_FAILURE; 73 | } 74 | 75 | if (argc - optind != 2) 76 | goto usage; 77 | 78 | const char *source = argv[optind]; 79 | const char *property = argv[optind + 1]; 80 | LIPCcode code; 81 | LIPC *lipc; 82 | 83 | openlog("lipc-get-prop", LOG_PID | LOG_CONS, LOG_LOCAL0); 84 | LipcSetLlog(LAB126_LOG_ALL & ~LAB126_LOG_DEBUG_ALL); 85 | 86 | if ((lipc = LipcOpenNoName()) == NULL) { 87 | if (g_lab126_log_mask & LAB126_LOG_ERROR) 88 | syslog(LOG_ERR, "E def:open::Failed to open LIPC"); 89 | fprintf(stderr, "error: failed to open lipc\n"); 90 | return EXIT_FAILURE; 91 | } 92 | 93 | switch (kind) { 94 | case PROPERTY_INT: { 95 | int value; 96 | if ((code = LipcGetIntProperty(lipc, source, property, &value)) == LIPC_OK) 97 | printf("%d", value); 98 | break; 99 | } 100 | case PROPERTY_STR: { 101 | char *value; 102 | if ((code = LipcGetStringProperty(lipc, source, property, &value)) == LIPC_OK) { 103 | printf("%s", value); 104 | LipcFreeString(value); 105 | } 106 | break; 107 | } 108 | case PROPERTY_HAS: { 109 | LIPCha *ha = NULL; 110 | char *value = NULL; 111 | size_t size = 0; 112 | if ((code = LipcAccessHasharrayProperty(lipc, source, property, NULL, &ha)) == LIPC_OK && 113 | (code = LipcHasharrayToString(ha, NULL, &size)) == LIPC_OK && 114 | (code = LipcHasharrayToString(ha, value = malloc(size), &size)) == LIPC_OK) 115 | printf(" %s", value); 116 | if (ha != NULL) 117 | LipcHasharrayDestroy(ha); 118 | free(value); 119 | }} 120 | 121 | if (code == LIPC_OK && end_nl) 122 | printf("\n"); 123 | 124 | if (code != LIPC_OK && !quiet) { 125 | if (g_lab126_log_mask & LAB126_LOG_ERROR) 126 | syslog(LOG_ERR, "E def:fail:source=%s, prop=%s:Failed to get property", source, property); 127 | fprintf(stderr, "error: %s failed to access property %s (0x%x %s)\n", 128 | source, property, code, LipcGetErrorString(code)); 129 | } 130 | 131 | LipcClose(lipc); 132 | return code == LIPC_OK ? EXIT_SUCCESS : EXIT_FAILURE; 133 | } 134 | -------------------------------------------------------------------------------- /src/lipc-probe.c: -------------------------------------------------------------------------------- 1 | /* 2 | * [open]lipc - lipc-probe.c 3 | * Copyright (c) 2016 Arkadiusz Bokowy 4 | * 5 | * This file is a part of openlipc. 6 | * 7 | * This project is licensed under the terms of the MIT license. 8 | * 9 | * This source code is based on the reverse-engineered application, which 10 | * is a part of the Kindle firmware. The original lipc-probe application is 11 | * copyrighted under the terms of the Amazon Technologies, Inc. 12 | * 13 | */ 14 | 15 | #include "openlipc.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | 26 | #define LIPC_PROPERTY_MODE_R 0x01 27 | #define LIPC_PROPERTY_MODE_W 0x02 28 | #define LIPC_PROPERTY_TYPE_INT 1 29 | #define LIPC_PROPERTY_TYPE_STR 2 30 | #define LIPC_PROPERTY_TYPE_HAS 3 31 | 32 | struct lipc_property { 33 | gchar *name; 34 | guchar mode; 35 | guchar type; 36 | }; 37 | 38 | 39 | /* Get the list of all available sources. On success, this function returns 40 | * TRUE and sources (publishers) are populated into the sources argument. On 41 | * failure FALSE is returned and the sources argument is not modified. */ 42 | static gboolean get_sources(GSList **sources) { 43 | 44 | GDBusConnection *dbus; 45 | GDBusMessage *message; 46 | GDBusMessage *reply; 47 | GVariantIter *iter; 48 | GError *error; 49 | gchar *address; 50 | gchar *tmp; 51 | gboolean rv; 52 | 53 | /* Kindle uses glib-2.29 but g_type_init is deprecated since glib-2.36, so 54 | * this call is pretty much required - omitting it will cause segfault. */ 55 | g_type_init(); 56 | 57 | message = reply = NULL; 58 | error = NULL; 59 | 60 | address = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, NULL); 61 | dbus = g_dbus_connection_new_for_address_sync(address, 62 | G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | 63 | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, 64 | NULL, NULL, &error); 65 | if (dbus == NULL) { 66 | fprintf(stderr, "error: failed to get DBus connection: %s\n", error->message); 67 | goto fail; 68 | } 69 | 70 | message = g_dbus_message_new_method_call("org.freedesktop.DBus", 71 | "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames"); 72 | reply = g_dbus_connection_send_message_with_reply_sync(dbus, message, 73 | G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &error); 74 | if (reply == NULL) { 75 | fprintf(stderr, "error: failed to get source list: %s\n", error->message); 76 | goto fail; 77 | } 78 | 79 | g_variant_get(g_dbus_message_get_body(reply), "(as)", &iter); 80 | while (g_variant_iter_loop(iter, "&s", &tmp)) { 81 | if (tmp[0] == ':' || g_ascii_strcasecmp(tmp, "org.freedesktop.DBus") == 0) 82 | continue; 83 | *sources = g_slist_prepend(*sources, g_strdup(tmp)); 84 | } 85 | g_variant_iter_free(iter); 86 | 87 | rv = TRUE; 88 | goto final; 89 | 90 | fail: 91 | g_error_free(error); 92 | rv = FALSE; 93 | 94 | final: 95 | if (reply != NULL) 96 | g_object_unref(reply); 97 | if (message != NULL) 98 | g_object_unref(message); 99 | if (dbus != NULL) 100 | g_object_unref(dbus); 101 | g_free(address); 102 | return rv; 103 | } 104 | 105 | /* Get the list of all properties for given source. On success, this function 106 | * returns TRUE and properties are populated into the properties argument. On 107 | * failure FALSE is returned and the properties argument is not modified. The 108 | * returned property is in the format of LipcProperty structure which can be 109 | * freed with g_free() function. */ 110 | static gboolean get_properties(LIPC *lipc, const char *source, GSList **properties) { 111 | 112 | char *values; 113 | 114 | if (LipcGetProperties(lipc, source, &values) != LIPC_OK) 115 | return FALSE; 116 | 117 | struct lipc_property property; 118 | gchar **tokens; 119 | guint i, length; 120 | 121 | tokens = g_strsplit(values, " ", 0); 122 | length = g_strv_length(tokens) / 3; 123 | for (i = 0; i < length; i++) { 124 | 125 | property.name = g_strdup(tokens[i * 3]); 126 | 127 | property.type = LIPC_PROPERTY_TYPE_HAS; 128 | if (g_strcmp0(tokens[i * 3 + 1], "Int") == 0) 129 | property.type = LIPC_PROPERTY_TYPE_INT; 130 | if (g_strcmp0(tokens[i * 3 + 1], "Str") == 0) 131 | property.type = LIPC_PROPERTY_TYPE_STR; 132 | 133 | property.mode = 0; 134 | if (strchr(tokens[i * 3 + 2], 'r') != NULL) 135 | property.mode |= LIPC_PROPERTY_MODE_R; 136 | if (strchr(tokens[i * 3 + 2], 'w') != NULL) 137 | property.mode |= LIPC_PROPERTY_MODE_W; 138 | 139 | *properties = g_slist_prepend(*properties, g_memdup(&property, sizeof(property))); 140 | 141 | } 142 | 143 | g_strfreev(tokens); 144 | LipcFreeString(values); 145 | return TRUE; 146 | } 147 | 148 | static const gchar *get_property_mode_str(guint mode) { 149 | switch (mode) { 150 | case LIPC_PROPERTY_MODE_R: 151 | return "r"; 152 | case LIPC_PROPERTY_MODE_W: 153 | return "w"; 154 | default: 155 | return "rw"; 156 | } 157 | } 158 | 159 | static const gchar *get_property_type_str(guint type) { 160 | switch (type) { 161 | case LIPC_PROPERTY_TYPE_INT: 162 | return "Int"; 163 | case LIPC_PROPERTY_TYPE_STR: 164 | return "Str"; 165 | default: 166 | return "Has"; 167 | } 168 | } 169 | 170 | static gint property_name_cmp(gconstpointer a, gconstpointer b) { 171 | struct lipc_property *_a = (struct lipc_property *)a; 172 | struct lipc_property *_b = (struct lipc_property *)b; 173 | return g_ascii_strcasecmp(_a->name, _b->name); 174 | } 175 | 176 | int main(int argc, char *argv[]) { 177 | 178 | int opt; 179 | 180 | int list_all = 0; 181 | int value_probe = 1; 182 | int value_get = 0; 183 | 184 | while ((opt = getopt(argc, argv, "hlav")) != -1) 185 | switch (opt) { 186 | case 'h': 187 | printf("usage: %s [-lav] [] [] ...\n\n" 188 | " publisher - the unique name of the publisher\n" 189 | "\n" 190 | "options:\n" 191 | " -l\tlist all available services in the system\n" 192 | " -a\tlist and probe all available services\n" 193 | " -v\tshow value for all readable properties\n", 194 | argv[0]); 195 | return EXIT_SUCCESS; 196 | 197 | case 'l': 198 | list_all = 1; 199 | value_probe = 0; 200 | break; 201 | case 'a': 202 | list_all = 1; 203 | value_probe = 1; 204 | break; 205 | case 'v': 206 | value_get = 1; 207 | break; 208 | 209 | default: 210 | usage: 211 | fprintf(stderr, "Try '%s -h' for more information.\n", argv[0]); 212 | return EXIT_FAILURE; 213 | } 214 | 215 | GSList *sources = NULL; 216 | LIPC *lipc; 217 | 218 | if (list_all) { 219 | if (get_sources(&sources) == FALSE) 220 | return EXIT_FAILURE; 221 | } 222 | else { 223 | while (argc - optind) 224 | sources = g_slist_prepend(sources, g_strdup(argv[optind++])); 225 | if (sources == NULL) 226 | goto usage; 227 | } 228 | 229 | LipcSetLlog(LAB126_LOG_ALL & ~LAB126_LOG_DEBUG_ALL); 230 | if ((lipc = LipcOpenNoName()) == NULL) { 231 | fprintf(stderr, "error: failed to open lipc\n"); 232 | return EXIT_FAILURE; 233 | } 234 | 235 | /* help reading the output by sorting input sources */ 236 | sources = g_slist_sort(sources, (GCompareFunc)g_ascii_strcasecmp); 237 | 238 | GSList *tmp; 239 | while (sources) { 240 | const char *source = (char *)sources->data; 241 | 242 | printf("%s\n", source); 243 | if (value_probe) { 244 | 245 | GSList *properties = NULL; 246 | get_properties(lipc, source, &properties); 247 | 248 | /* help reading the output by sorting properties */ 249 | properties = g_slist_sort(properties, property_name_cmp); 250 | 251 | GSList *tmp; 252 | while (properties) { 253 | struct lipc_property *property = (struct lipc_property *)properties->data; 254 | 255 | printf("\t%s\t%s\t%s", get_property_mode_str(property->mode), 256 | get_property_type_str(property->type), property->name); 257 | 258 | if (value_get && property->mode && LIPC_PROPERTY_MODE_R) { 259 | 260 | if (property->type == LIPC_PROPERTY_TYPE_INT) { 261 | int value; 262 | if (LipcGetIntProperty(lipc, source, property->name, &value) == LIPC_OK) 263 | printf("\t[%d]", value); 264 | } 265 | else if (property->type == LIPC_PROPERTY_TYPE_STR) { 266 | char *value; 267 | if (LipcGetStringProperty(lipc, source, property->name, &value) == LIPC_OK) { 268 | printf("\t[%s]", value); 269 | LipcFreeString(value); 270 | } 271 | } 272 | else 273 | printf("\t[*NOT SHOWN*]"); 274 | 275 | } 276 | 277 | printf("\n"); 278 | 279 | /* free resources and get next element */ 280 | g_free(property->name); 281 | g_free(properties->data); 282 | tmp = g_slist_next(properties); 283 | g_slist_free_1(properties); 284 | properties = tmp; 285 | 286 | } 287 | 288 | } 289 | 290 | /* free resources and get next element */ 291 | g_free(sources->data); 292 | tmp = g_slist_next(sources); 293 | g_slist_free_1(sources); 294 | sources = tmp; 295 | 296 | } 297 | 298 | LipcClose(lipc); 299 | return EXIT_SUCCESS; 300 | } 301 | -------------------------------------------------------------------------------- /src/lipc-set-prop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * [open]lipc - lipc-set-prop.c 3 | * Copyright (c) 2016 Arkadiusz Bokowy 4 | * 5 | * This file is a part of openlipc. 6 | * 7 | * This project is licensed under the terms of the MIT license. 8 | * 9 | * This source code is based on the reverse-engineered application, which is 10 | * a part of the Kindle firmware. The original lipc-set-prop application is 11 | * copyrighted under the terms of the Amazon Technologies, Inc. 12 | * 13 | */ 14 | 15 | #include "openlipc.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | int main(int argc, char *argv[]) { 24 | 25 | int opt; 26 | 27 | int integer = 0; 28 | int string = 0; 29 | int quiet = 0; 30 | 31 | while ((opt = getopt(argc, argv, "hisq")) != -1) 32 | switch (opt) { 33 | case 'h': 34 | printf("usage: %s [-isq] \n\n" 35 | " publisher - the unique name of the publisher\n" 36 | " property - the name of the property to set\n" 37 | " value - the value to set\n" 38 | "\n" 39 | "options:\n" 40 | " -i\tpublisher published an integer property\n" 41 | " -s\tpublisher published a string property\n" 42 | " -q\tdo not print error message\n" 43 | "\n" 44 | "The type of the value is assumed to be an integer by default. If the coercion\n" 45 | "fails, the string is used instead. One can override this behavior by using one\n" 46 | "of the -i or -s option.\n", 47 | argv[0]); 48 | return EXIT_SUCCESS; 49 | 50 | case 'i': 51 | integer = 1; 52 | break; 53 | case 's': 54 | string = 1; 55 | break; 56 | case 'q': 57 | quiet = 1; 58 | break; 59 | 60 | default: 61 | usage: 62 | fprintf(stderr, "Try '%s -h' for more information.\n", argv[0]); 63 | return EXIT_FAILURE; 64 | } 65 | 66 | if (argc - optind != 3) 67 | goto usage; 68 | 69 | const char *source = argv[optind]; 70 | const char *property = argv[optind + 1]; 71 | const char *value = argv[optind + 2]; 72 | LIPCcode code; 73 | LIPC *lipc; 74 | 75 | openlog("lipc-set-prop", LOG_PID | LOG_CONS, LOG_LOCAL0); 76 | LipcSetLlog(LAB126_LOG_ALL & ~LAB126_LOG_DEBUG_ALL); 77 | 78 | if ((lipc = LipcOpenNoName()) == NULL) { 79 | if (g_lab126_log_mask & LAB126_LOG_ERROR) 80 | syslog(LOG_ERR, "E def:open::Failed to open LIPC"); 81 | fprintf(stderr, "error: failed to open lipc\n"); 82 | return EXIT_FAILURE; 83 | } 84 | 85 | char *tmp; 86 | int value_int; 87 | value_int = strtol(value, &tmp, 10); 88 | 89 | if (integer) { 90 | if (*tmp != '\0') { 91 | if (!quiet) 92 | fprintf(stderr, "error: value is not an integer\n"); 93 | code = LIPC_ERROR_INVALID_ARG; 94 | goto fail; 95 | } 96 | code = LipcSetIntProperty(lipc, source, property, value_int); 97 | } 98 | else if (string) { 99 | code = LipcSetStringProperty(lipc, source, property, value); 100 | } 101 | else { 102 | if (*tmp == '\0') 103 | code = LipcSetIntProperty(lipc, source, property, value_int); 104 | else 105 | code = LipcSetStringProperty(lipc, source, property, value); 106 | } 107 | 108 | if (code != LIPC_OK && !quiet) { 109 | if (g_lab126_log_mask & LAB126_LOG_ERROR) 110 | syslog(LOG_ERR, "E def:fail:source=%s, prop=%s:Failed to set property", source, property); 111 | fprintf(stderr, "error: %s failed to set value for property %s (0x%x %s)\n", 112 | source, property, code, LipcGetErrorString(code)); 113 | } 114 | 115 | fail: 116 | LipcClose(lipc); 117 | return code == LIPC_OK ? EXIT_SUCCESS : EXIT_FAILURE; 118 | } 119 | -------------------------------------------------------------------------------- /test/Makefile.am: -------------------------------------------------------------------------------- 1 | # [open]lipc - Makefile.am 2 | # Copyright (c) 2016 Arkadiusz Bokowy 3 | 4 | AM_CFLAGS = -I$(top_srcdir)/include 5 | LDADD = -llipc 6 | 7 | check_PROGRAMS = \ 8 | lipc-test-init \ 9 | lipc-test-hasharray \ 10 | lipc-test-prop \ 11 | lipc-test-event 12 | 13 | if ENABLE_KINDLE_ENV 14 | AM_LDFLAGS = \ 15 | -L$(KINDLE_ROOTDIR)/lib \ 16 | -L$(KINDLE_ROOTDIR)/usr/lib \ 17 | -Wl,-rpath=$(KINDLE_ROOTDIR)/lib \ 18 | -Wl,-rpath=$(KINDLE_ROOTDIR)/usr/lib 19 | endif 20 | -------------------------------------------------------------------------------- /test/lipc-test-event.c: -------------------------------------------------------------------------------- 1 | /* 2 | * [open]lipc - lipc-test-event.c 3 | * Copyright (c) 2016 Arkadiusz Bokowy 4 | * 5 | * This file is a part of openlipc. 6 | * 7 | * This project is licensed under the terms of the MIT license. 8 | * 9 | */ 10 | 11 | #include "openlipc.h" 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | static int event_count = 0; 19 | 20 | 21 | LIPCcode event(LIPC *lipc, const char *name, LIPCevent *event, void *data) { 22 | 23 | int value_i; 24 | char *value_s; 25 | 26 | assert(strcmp(LipcGetServiceName(lipc), "com.example") == 0); 27 | assert(strcmp(name, "event") == 0); 28 | 29 | assert(strcmp(LipcGetServiceName(lipc), LipcGetEventSource(event)) == 0); 30 | assert(strcmp(name, LipcGetEventName(event)) == 0); 31 | assert((long int)data == 0xABCD); 32 | 33 | if (event_count == 0) { 34 | 35 | LipcGetIntParam(event, &value_i); 36 | assert(value_i == 0xDEAD); 37 | LipcGetStringParam(event, &value_s); 38 | assert(strcmp(value_s, "OK") == 0); 39 | LipcGetIntParam(event, &value_i); 40 | assert(value_i == 0xE220); 41 | 42 | LipcRewindParams(event); 43 | LipcGetIntParam(event, &value_i); 44 | assert(value_i == 0xDEAD); 45 | 46 | } 47 | 48 | event_count++; 49 | return LIPC_OK; 50 | } 51 | 52 | int main(void) { 53 | 54 | LIPC *lipc; 55 | 56 | lipc = LipcOpen("com.example"); 57 | 58 | assert(LipcSubscribeExt(lipc, "com.example", "event", event, (void *)0xABCD) == LIPC_OK); 59 | 60 | LipcCreateAndSendEventWithParameters(lipc, "event", "%d%s%d", 0xDEAD, "OK", 0xE220); 61 | assert(event_count == 1); 62 | 63 | LipcClose(lipc); 64 | 65 | return EXIT_SUCCESS; 66 | } 67 | -------------------------------------------------------------------------------- /test/lipc-test-hasharray.c: -------------------------------------------------------------------------------- 1 | /* 2 | * [open]lipc - lipc-test-hasharray.c 3 | * Copyright (c) 2016 Arkadiusz Bokowy 4 | * 5 | * This file is a part of openlipc. 6 | * 7 | * This project is licensed under the terms of the MIT license. 8 | * 9 | */ 10 | 11 | #include "openlipc.h" 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | int main(void) { 19 | 20 | LIPC *lipc; 21 | LIPCha *ha; 22 | 23 | assert((lipc = LipcOpenNoName()) != NULL); 24 | 25 | assert((ha = LipcHasharrayNew(lipc)) != NULL); 26 | assert(LipcHasharrayFree(ha, 1) == LIPC_OK); 27 | 28 | /* add new hash map to the array */ 29 | 30 | assert((ha = LipcHasharrayNew(lipc)) != NULL); 31 | assert(LipcHasharrayGetHashCount(ha) == 0); 32 | 33 | size_t index = 0xDEAD; 34 | assert(LipcHasharrayAddHash(ha, &index) == LIPC_OK); 35 | assert(LipcHasharrayGetHashCount(ha) == 1); 36 | assert(index == 0); 37 | 38 | /* add values to the hash map structure */ 39 | 40 | const char *key_int = "Int"; 41 | const char string[] = "Value"; 42 | const unsigned char blob[] = { 1, 2, 0, 4, 5 }; 43 | assert(LipcHasharrayPutInt(ha, 0, key_int, 0xB00B) == LIPC_OK); 44 | assert(LipcHasharrayPutString(ha, 0, "Key", string) == LIPC_OK); 45 | assert(LipcHasharrayPutBlob(ha, 0, "Doom", blob, sizeof(blob)) == LIPC_OK); 46 | 47 | /* get the number of added hash values */ 48 | 49 | const char *keys[3]; 50 | size_t count = 0; 51 | 52 | assert(LipcHasharrayKeys(ha, 0, NULL, &count) == LIPC_OK); 53 | assert(count == 3); 54 | 55 | assert(LipcHasharrayKeys(ha, 0, keys, &count) == LIPC_OK); 56 | assert(strcmp(keys[0], key_int) == 0); 57 | assert(strcmp(keys[2], "Doom") == 0); 58 | /* check if key is stored internally */ 59 | assert(keys[0] != key_int); 60 | 61 | /* check data types */ 62 | 63 | LIPCHasharrayType type; 64 | size_t size; 65 | 66 | assert(LipcHasharrayCheckKey(ha, 0, key_int, &type, &size) == LIPC_OK); 67 | assert(type == LIPC_HASHARRAY_INT); 68 | assert(size == sizeof(0xB00B)); 69 | assert(LipcHasharrayCheckKey(ha, 0, "Key", &type, &size) == LIPC_OK); 70 | assert(type == LIPC_HASHARRAY_STRING); 71 | assert(size == sizeof(string)); 72 | assert(LipcHasharrayCheckKey(ha, 0, "Doom", &type, &size) == LIPC_OK); 73 | assert(type == LIPC_HASHARRAY_BLOB); 74 | assert(size == sizeof(blob)); 75 | 76 | /* get added values */ 77 | 78 | int value_int; 79 | assert(LipcHasharrayGetInt(ha, 0, key_int, &value_int) == LIPC_OK); 80 | assert(value_int == 0xB00B); 81 | 82 | char *string_; 83 | assert(LipcHasharrayGetString(ha, 0, "Key", &string_) == LIPC_OK); 84 | assert(strcmp(string_, string) == 0); 85 | /* check if value is stored internally */ 86 | assert(string_ != key_int); 87 | 88 | unsigned char *blob_; 89 | assert(LipcHasharrayGetBlob(ha, 0, "Doom", &blob_, &size) == LIPC_OK); 90 | assert(size == sizeof(blob)); 91 | assert(memcmp(blob_, blob, size) == 0); 92 | /* check if value is stored internally */ 93 | assert((void *)blob_ != (void *)blob); 94 | 95 | /* string representation */ 96 | 97 | char buffer[512]; 98 | size_t buffer_size = sizeof(buffer); 99 | assert(LipcHasharrayToString(ha, buffer, &buffer_size) == LIPC_OK); 100 | assert(strcmp(buffer, "0:{ Int=45067 Key=\"Value\" Doom=(binary) }\n ") == 0); 101 | assert(buffer_size == 43); 102 | 103 | /* copying entire structure */ 104 | 105 | LIPCha *ha_; 106 | char buffer_[512]; 107 | 108 | assert((ha_ = LipcHasharrayNew(lipc)) != NULL); 109 | assert(LipcHasharrayCopy(ha_, ha) == LIPC_OK); 110 | buffer_size = sizeof(buffer_); 111 | assert(LipcHasharrayToString(ha_, buffer_, &buffer_size) == LIPC_OK); 112 | assert(strcmp(buffer_, buffer) == 0); 113 | LipcHasharrayDestroy(ha_); 114 | 115 | assert((ha_ = LipcHasharrayClone(ha)) != NULL); 116 | buffer_size = sizeof(buffer_); 117 | assert(LipcHasharrayToString(ha_, buffer_, &buffer_size) == LIPC_OK); 118 | assert(strcmp(buffer_, buffer) == 0); 119 | LipcHasharrayDestroy(ha_); 120 | 121 | LipcHasharrayDestroy(ha); 122 | LipcClose(lipc); 123 | 124 | return EXIT_SUCCESS; 125 | } 126 | -------------------------------------------------------------------------------- /test/lipc-test-init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * [open]lipc - lipc-test-init.c 3 | * Copyright (c) 2016 Arkadiusz Bokowy 4 | * 5 | * This file is a part of openlipc. 6 | * 7 | * This project is licensed under the terms of the MIT license. 8 | * 9 | */ 10 | 11 | #include "openlipc.h" 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | int main(void) { 19 | 20 | LIPC *lipc; 21 | LIPCcode code; 22 | 23 | assert((lipc = LipcOpenNoName()) != NULL); 24 | assert(LipcGetServiceName(lipc) == NULL); 25 | LipcClose(lipc); 26 | 27 | assert((lipc = LipcOpen("com.example")) != NULL); 28 | assert(strcmp(LipcGetServiceName(lipc), "com.example") == 0); 29 | LipcClose(lipc); 30 | 31 | code = LIPC_ERROR_UNKNOWN; 32 | assert((lipc = LipcOpenEx("com.example", &code)) != NULL); 33 | assert(strcmp(LipcGetServiceName(lipc), "com.example") == 0); 34 | assert(code == LIPC_OK); 35 | LipcClose(lipc); 36 | 37 | assert(strcmp(LipcGetErrorString(LIPC_OK), "lipcErrNone") == 0); 38 | 39 | return EXIT_SUCCESS; 40 | } 41 | -------------------------------------------------------------------------------- /test/lipc-test-prop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * [open]lipc - lipc-test-prop.c 3 | * Copyright (c) 2016 Arkadiusz Bokowy 4 | * 5 | * This file is a part of openlipc. 6 | * 7 | * This project is licensed under the terms of the MIT license. 8 | * 9 | */ 10 | 11 | #include "openlipc.h" 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | static int prop_int = 0xDEAD; 19 | static char prop_str[64] = "Yes! Yes! Yes!"; 20 | static int prop_s_size = 0; 21 | 22 | LIPCcode getter(LIPC *lipc, const char *property, void *value, void *data) { 23 | (void)lipc; 24 | 25 | int i = strcmp(property, "int") == 0; 26 | int s = strcmp(property, "str") == 0; 27 | int _data = (long int)(data); 28 | 29 | assert(i || s); 30 | 31 | if (i) { 32 | assert(_data == 0x1111); 33 | LIPC_GETTER_VTOI(value) = prop_int; 34 | } 35 | 36 | if (s) { 37 | 38 | if (!prop_s_size || *(int *)data < 500) { 39 | assert(++prop_s_size == 1); 40 | *(int *)data = 500; 41 | return LIPC_ERROR_BUFFER_TOO_SMALL; 42 | } 43 | 44 | assert(prop_s_size == 1); 45 | strncpy(LIPC_GETTER_VTOS(value), prop_str, *(int *)data); 46 | 47 | } 48 | 49 | return LIPC_OK; 50 | } 51 | 52 | LIPCcode setter(LIPC *lipc, const char *property, void *value, void *data) { 53 | (void)lipc; 54 | 55 | int i = strcmp(property, "int") == 0; 56 | int s = strcmp(property, "str") == 0; 57 | int _data = (long int)(data); 58 | 59 | assert(i || s); 60 | 61 | if (i) { 62 | assert(_data == 0x1111); 63 | prop_int = LIPC_SETTER_VTOI(value); 64 | } 65 | 66 | if (s) { 67 | assert(_data == 0x2222); 68 | strncpy(prop_str, LIPC_SETTER_VTOS(value), sizeof(prop_str) - 1); 69 | } 70 | 71 | return LIPC_OK; 72 | } 73 | 74 | int main(void) { 75 | 76 | LIPC *lipc; 77 | char *value_s; 78 | int value_i; 79 | 80 | lipc = LipcOpen("com.example"); 81 | 82 | assert(LipcRegisterIntProperty(lipc, "int", getter, setter, (void *)0x1111) == LIPC_OK); 83 | assert(LipcRegisterStringProperty(lipc, "str", getter, setter, (void *)0x2222) == LIPC_OK); 84 | 85 | /* get default property values */ 86 | 87 | assert(LipcGetIntProperty(lipc, "com.example", "int", &value_i) == LIPC_OK); 88 | assert(value_i == prop_int); 89 | 90 | assert(LipcGetStringProperty(lipc, "com.example", "str", &value_s) == LIPC_OK); 91 | assert(strcmp(value_s, prop_str) == 0); 92 | LipcFreeString(value_s); 93 | 94 | /* set property values */ 95 | 96 | assert(LipcSetIntProperty(lipc, "com.example", "int", 0xBEEF) == LIPC_OK); 97 | assert(prop_int == 0xBEEF); 98 | 99 | assert(LipcSetStringProperty(lipc, "com.example", "str", "No!") == LIPC_OK); 100 | assert(strcmp(prop_str, "No!") == 0); 101 | 102 | /* get list of registered properties */ 103 | 104 | assert(LipcGetProperties(lipc, "com.example", &value_s) == LIPC_OK); 105 | assert(strcmp(value_s, "str Str rw int Int rw ") == 0); 106 | LipcFreeString(value_s); 107 | 108 | /* get not registered property */ 109 | 110 | assert(LipcGetIntProperty(lipc, "com.example", "xxx", &value_i) == LIPC_ERROR_NO_SUCH_PROPERTY); 111 | 112 | int tmp; 113 | assert(LipcUnregisterProperty(lipc, "int", NULL) == LIPC_OK); 114 | assert(LipcUnregisterProperty(lipc, "str", (void *)&tmp) == LIPC_OK); 115 | assert(tmp == 0x2222); 116 | 117 | /* test access mode setting */ 118 | 119 | assert(LipcRegisterIntProperty(lipc, "int", getter, NULL, NULL) == LIPC_OK); 120 | assert(LipcRegisterStringProperty(lipc, "str", NULL, setter, NULL) == LIPC_OK); 121 | 122 | assert(LipcGetProperties(lipc, "com.example", &value_s) == LIPC_OK); 123 | assert(strcmp(value_s, "str Str w int Int r ") == 0); 124 | LipcFreeString(value_s); 125 | 126 | value_s = (char *)0xDEAD; 127 | assert(LipcSetIntProperty(lipc, "com.example", "int", 0x0C0C) == LIPC_ERROR_ACCESS_NOT_ALLOWED); 128 | assert(LipcGetStringProperty(lipc, "com.example", "str", &value_s) == LIPC_ERROR_ACCESS_NOT_ALLOWED); 129 | assert(value_s == (char *)0xDEAD); 130 | 131 | assert(LipcUnregisterProperty(lipc, "int", NULL) == LIPC_OK); 132 | assert(LipcUnregisterProperty(lipc, "str", NULL) == LIPC_OK); 133 | 134 | LipcClose(lipc); 135 | 136 | return EXIT_SUCCESS; 137 | } 138 | --------------------------------------------------------------------------------