1 /*
2   Copyright (C) 2006-2013 Werner Dittmann
3 
4   This program is free software: you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as published by
6   the Free Software Foundation, either version 3 of the License, or
7   (at your option) any later version.
8 
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13 
14   You should have received a copy of the GNU General Public License
15   along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #ifndef _ZRTP_CACHE_DB_BACKEND_H_
19 #define _ZRTP_CACHE_DB_BACKEND_H_
20 
21 #include <libzrtpcpp/ZIDRecordDb.h>
22 
23 #if defined(__cplusplus)
24 extern "C"
25 {
26 #endif
27 
28 #define DB_CACHE_ERR_BUFF_SIZE  1000
29 
30 /**
31  * Set of accessible operations of database ZRTP cache implementaion.
32  *
33  * The only public method of the database ZRTP implementation is
34  * getDbCacheOps(...)  that fills in this call structure. This mechanism
35  * decouples the database implementations from libzrtp and possible other
36  * clients.
37  *
38  * Some implementation notes:
39  * <ul>
40  * <li> All data storage methods return 0 (zero) if the call was successful.
41  * </li>
42 
43  * <li> The @c errString parameter points to a buffer of at least @c
44  *      DB_CACHE_ERR_BUFF_SIZE character. In case of an error methods shall
45  *      store detailed, human readable information in this buffer. Use @c
46  *      snprintf or similar functions to format the data.  If this parameter
47  *      is @c NULL then methods must not return an error string.
48  *</li>
49  * <li> The methods cast the @c void to the type they need. Be aware that the
50  *      open functions requires a pointer to a pointer.
51  * </li>
52  * </ul>
53  *
54  *
55  *
56  */
57 typedef struct {
58     /**
59      * @brief Open the cache.
60      *
61      * @param name String that identifies the database or data storage.
62      *
63      * @param pdb Pointer to an internal structure that the database
64      *            implementation requires.
65      *
66      * @param errString Pointer to a character buffer, see implementation
67      *                  notes above.
68      */
69     int (*openCache)(const char* name, void **pdb, char *errString);
70 
71     /**
72      * Close the cache.
73      *
74      * @param db Pointer to an internal structure that the database
75      *           implementation requires.
76      */
77     int (*closeCache)(void *db);
78 
79     /**
80      * @brief Read a local ZID from the database.
81      *
82      * The cache database may implement methods to generate and store local
83      * ZRTP identifiers (ZID) and optionally link them with account
84      * information. The account information data is the key to the request
85      * local ZID. If the application does not provide account information data
86      * the method implmentation shall use a standard predfined string that
87      * does not collide with usual account information.
88      *
89      * The SQLite backend uses the string @c "_STANDARD_" in this case and
90      * sets a specific type field.
91      *
92      * The first call to this method with a specific account information
93      * generates a ZID, stores it in the database usind the account
94      * information as key, and returns the ZID to the application. Any
95      * subsequent call with the same account information return the same local
96      * ZID.
97      *
98      * @param db Pointer to an internal structure that the database
99      *           implementation requires.
100      *
101      * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
102      *                 uint8_t bytes. The method stores the local ZID in this
103      *                 buffer.
104      *
105      * @param accountInfo Pointer to an account information string or @c NULL
106      *                    if explicit account information is not required.
107      *
108      * @param errString Pointer to a character buffer, see implementation
109      *                  notes above.
110      */
111     int (*readLocalZid)(void *db, uint8_t *localZid, const char *accountInfo, char *errString);
112 
113     /**
114      * @brief Read a remote ZID data structure.
115      *
116      * The method uses @c remoteZid and @c localZid as keys to read the remote
117      * ZID record.  If a record does not exist in the database the method
118      * clears the @c flags field in the @c remoteZidRecord_t structure and
119      * returns without error. The application must check the flags if the
120      * method found a valid record.
121      *
122      * @param db Pointer to an internal structure that the database
123      *           implementation requires.
124      *
125      * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
126      *                 uint8_t bytes. The buffer must contain the local ZID.
127      *
128      * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
129      *                  uint8_t bytes. The buffer must contain the remote ZID.
130      *
131      * @param remZid Pointer to the @c remoteZidRecord_t structure. The method
132      *               fills this structure with data it read from the database.
133      *
134      * @param errString Pointer to a character buffer, see implementation
135      *                  notes above.
136      */
137     int (*readRemoteZidRecord)(void *db, const uint8_t *remoteZid, const uint8_t *localZid,
138                                remoteZidRecord_t *remZid, char* errString);
139     /**
140      * @brief Update an existing remote ZID data structure.
141      *
142      * The method uses @c remoteZid and @c localZid as keys to update an
143      * existing remote ZID record.
144      *
145      * @b NOTE: application must use this methods only if
146      *          @c readRemoteZidRecord (see above) returned a @b valid record. If
147      *          @c readRemoteZidRecord returned an invalid record then no such
148      *          record exists in the database and the application must use the
149      *          @c insertRemoteZidRecord (see below).
150      *
151      * @param db Pointer to an internal structure that the database
152      *           implementation requires.
153      *
154      * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
155      *                 uint8_t bytes. The buffer must contain the local ZID.
156      *
157      * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
158      *                  uint8_t bytes. The buffer must contain the remote ZID.
159      *
160      * @param remZid Pointer to the @c remoteZidRecord_t structure. The method
161      *               gets data from this structure and stores it in the
162      *               database.
163      *
164      * @param errString Pointer to a character buffer, see implementation
165      *                  notes above.
166      */
167     int (*updateRemoteZidRecord)(void *db, const uint8_t *remoteZid, const uint8_t *localZid,
168                                  const remoteZidRecord_t *remZid, char* errString);
169     /**
170      * @brief Insert a new remote ZID data structure.
171      *
172      * The method uses @c remoteZid and @c localZid as keys to insert a new
173      * remote ZID record.
174      *
175      * @b NOTE: application must use this methods only if @c
176      *          readRemoteZidRecord (see above) returned an @b invalid
177      *          record. Refer to note.
178      *
179      * @param db Pointer to an internal structure that the database
180      *           implementation requires.
181      *
182      * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
183      *                 uint8_t bytes. The buffer must contain the local ZID.
184      *
185      * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
186      *                  uint8_t bytes. The buffer must contain the remote ZID.
187      *
188      * @param remZid Pointer to the @c remoteZidRecord_t structure. The method
189      *               gets data from this structure and stores it in the
190      *               database.
191      *
192      * @param errString Pointer to a character buffer, see implementation
193      *                  notes above.
194      */
195     int (*insertRemoteZidRecord)(void *db, const uint8_t *remoteZid, const uint8_t *localZid,
196                                  const remoteZidRecord_t *remZid, char* errString);
197 
198     /**
199      * @brief Read a remote ZID name.
200      *
201      * The method uses @c remoteZid, @c localZid, and @c accountInfo as keys
202      * to read the remote ZID name.  If a record does not exist in the database
203      * the method clears the @c flags field in the @c zidNameRecord_t structure and
204      * returns without error. The application must check the flags if the
205      * method found a valid record.
206      *
207      * @param vdb Pointer to an internal structure that the database
208      *           implementation requires.
209      *
210      * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
211      *                 uint8_t bytes. The buffer must contain the local ZID.
212      *
213      * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
214      *                  uint8_t bytes. The buffer must contain the remote ZID.
215      *
216      * @param accountInfo Pointer to an account information string or @c NULL
217      *                    if explicit account information is not required.
218      *
219      * @param zidName Pointer to the @c zidNameRecord_t structure. The method
220      *                returns the data in this structure.
221      *
222      * @param errString Pointer to a character buffer, see implementation
223      *                  notes above.
224      */
225     int (*readZidNameRecord)(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
226                              const char *accountInfo, zidNameRecord_t *zidName, char* errString);
227 
228     /**
229      * @brief Update an existing remote ZID data structure.
230      *
231      * The method uses @c remoteZid and @c localZid as keys to update an
232      * existing remote ZID record.
233      *
234      * @b NOTE: application must use this methods only if
235      *          @c readZidName (see above) returned a @b valid record. If
236      *          @c readZidName returned an invalid record then no such
237      *          record exists in the database and the application must use the
238      *          @c insertZidNameRecord (see below).
239      *
240      * @param vdb Pointer to an internal structure that the database
241      *           implementation requires.
242      *
243      * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
244      *                 uint8_t bytes. The buffer must contain the local ZID.
245      *
246      * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
247      *                  uint8_t bytes. The buffer must contain the remote ZID.
248      *
249      * @param accountInfo Pointer to an account information string or @c NULL
250      *                    if explicit account information is not required.
251      *
252      * @param zidName Pointer to the @c zidNameRecord_t structure. The method
253      *               gets data from this structure and stores it in the
254      *               database.
255      *
256      * @param errString Pointer to a character buffer, see implementation
257      *                  notes above.
258      */
259     int (*updateZidNameRecord)(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
260                                const char *accountInfo, zidNameRecord_t *zidName, char* errString);
261 
262     /**
263      * @brief Insert a new ZID name record.
264      *
265      * The method uses @c remoteZid, @c localZid, and @c accountInfo as keys to
266      * insert a new ZID name record.
267      *
268      * @b NOTE: application must use this methods only if @c readZidName
269      *         (see above) returned an @b invalid record.
270      *
271      * @param db Pointer to an internal structure that the database
272      *           implementation requires.
273      *
274      * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
275      *                 uint8_t bytes. The buffer must contain the local ZID.
276      *
277      * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
278      *                  uint8_t bytes. The buffer must contain the remote ZID.
279      *
280      * @param accountInfo Pointer to an account information string or @c NULL
281      *                    if explicit account information is not required.
282      *
283      * @param zidName Pointer to the @c zidNameRecord_t structure. The method
284      *               gets data from this structure and stores it in the
285      *               database.
286      *
287      * @param errString Pointer to a character buffer, see implementation
288      *                  notes above.
289      */
290     int (*insertZidNameRecord)(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
291                                const char *accountInfo, zidNameRecord_t *zidName, char* errString);
292 
293 
294     /**
295      * @brief Clean the cache.
296      *
297      * The function drops and re-creates all tables in the database. This removes all stored
298      * data. The application must not call this while a ZRTP call is active. Also the application
299      * <b>must</b> get the local ZID again.
300      *
301      * @param db Pointer to an internal structure that the database
302      *           implementation requires.
303      *
304      * @param errString Pointer to a character buffer, see implementation
305      *                  notes above.
306      */
307     int (*cleanCache)(void *db, char* errString);
308 
309     /**
310      * @brief Prepare a SQL cursor to read all records from the remote (peer) ZID table.
311      *
312      * The function creates a SQL cursor (prepares a statement in sqlite3 parlance) to
313      * read all records from the table that contains the remote (peers') ZID data.
314      *
315      * This functions returns a pointer to the SQL cursor or @c NULL if it fails to
316      * create a cursor.
317      *
318      * @param db Pointer to an internal structure that the database
319      *           implementation requires.
320      *
321      * @param errString Pointer to a character buffer, see implementation
322      *                  notes above.
323      *
324      * @return a void pointer to the sqlite3 statment (SQL cursor) or @c NULL
325      */
326     void *(*prepareReadAllZid)(void *db, char *errString);
327 
328     /**
329      * @brief Read next ZID record from and SQL cursor.
330      *
331      * The function reads the next ZID record from a SQL cursor. If it cannot read a
332      * record or encounters an error the function closes the cursor and returns @c NULL.
333      * In this case the function must not use the SQL cursor pointer again.
334      *
335      * @param db Pointer to an internal structure that the database
336      *           implementation requires.
337      *
338      * @param stmt a void pointer to a sqlite3 statement (SQL cursor)
339      *
340      * @param remZid Pointer to the @c remoteZidRecord_t structure. The method
341      *               fills this structure with data it read from the database.
342      *
343      * @param errString Pointer to a character buffer, see implementation
344      *                  notes above.
345      *
346      * @return void pointer to statment if successful, this is the same pointer as
347      *         the @c stmt input parameter. The function returns @c NULL if either
348      *         no more record is available or it got another error.
349      */
350     void *(*readNextZidRecord)(void *db, void *stmt, remoteZidRecord_t *remZid, char* errString);
351 
352     /**
353      * @brief Close sqlite3 statment (SQL cursor)
354      *
355      * This functions closes (finalizes) an open sqlite3 statment. Usually the
356      * @c readNextZidRecord closes the statment if no more record is available. However, an
357      * application may decide not to read every record. In this case it @b must close the
358      * sqlite3 statment
359      *
360      * @param stmt a void pointer to a sqlite3 statement (SQL cursor)
361      */
362     void (*closeStatement)(void *vstmt);
363 } dbCacheOps_t;
364 
365 void getDbCacheOps(dbCacheOps_t *ops);
366 
367 
368 #if defined(__cplusplus)
369 }
370 #endif
371 
372 #endif /* _ZRTP_CACHE_DB_BACKEND_H_*/
373