DVBCore  20.3.0
DVBCore Documentation
dba_nvm.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2013 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
25 //---includes for this file------------------------------------------------------------------------
26 #include <string.h>
27 
28 #include "techtype.h"
29 #include "dbgfuncs.h"
30 
31 #include "stbhwos.h"
32 
33 #include "dba.h"
34 #include "dba_nvm.h"
35 #include "stbdbram.h"
36 #include "stbdbnvm.h"
37 #include "stbnvm.h"
38 #include "stbcsum.h"
39 
40 #include "stbheap.h"
41 #include "stbuni.h"
42 
43 //---constant definitions for this file-------------------------------------------------------------
44 #define FORMAT_VERSION_NUM 4
45 #define FORMAT_ID_STRING "STB DB 01"
46 #define FORMAT_ID_STRING_SIZE 10
47 
48 #define NUM_FIELDS(X) (sizeof(X) / sizeof(FIELD_ACCESS))
49 
50 /* Length of various strings held in the database */
51 #define DBA_GROUP_NAME_LEN 35
52 #define DBA_SERV_NAME_LEN 32
53 #define DBA_TIMER_NAME_LEN 255 /* Max length of an event name is 255 chars */
54 #define DBA_FAVLIST_NAME_LEN 128 /* Arbitrary length */
55 #define DBA_TIMER_ADDINFO_LEN 255
56 #define DBA_LNB_NAME_LEN 24
57 
58 #define DBA_CRID_LEN 65
59 
60 /* CI+ specific strings */
61 #define DBA_PROFILE_NAME_LEN 255
62 
63 //---local typedefs, structs, enumerations for this file--------------------------------------------
64 
65 typedef struct
66 {
67  U8BIT id_str[FORMAT_ID_STRING_SIZE];
68  U8BIT spare[4];
69  U8BIT version;
70  U8BIT checksum;
72 
73 typedef struct
74 {
75  U16BIT desc_size;
76  U8BIT num_records;
77  U8BIT padding[1];
79 
80 typedef struct
81 {
82  U8BIT record_id;
83  U8BIT num_fields;
84  U16BIT first_block;
86 
87 typedef struct
88 {
89  U16BIT field_id;
90  U16BIT field_offset;
91  U16BIT field_size;
92  U8BIT padding[2];
94 
95 typedef struct
96 {
97  U16BIT field_id;
98  E_DBA_FIELD_TYPE type;
99 } FIELD_TYPE;
100 
101 typedef struct
102 {
103  U16BIT field_id;
104  U16BIT nvm_bit_offset;
105  U16BIT nvm_bit_size;
106  U16BIT ram_byte_offset;
107  U16BIT ram_byte_size;
108  U32BIT default_value;
109 } FIELD_ACCESS;
110 
111 typedef struct
112 {
113  U8BIT num_fields;
114  const FIELD_ACCESS *field;
115 } RECORD_ACCESS;
116 
117 
118 //---local (static) variable declarations for this file---------------------------------------------
119 // (internal variables declared static to make them local)
120 static const FIELD_TYPE database_field_type[] =
121 {
122  {DBA_FIELD_PARENT, UNUM_TYPE},
123  {DBA_FIELD_REC_NAME, STR_TYPE},
124  {DBA_FIELD_ORIG_NET_ID, UNUM_TYPE},
125  {DBA_FIELD_NET_ID, UNUM_TYPE},
126  {DBA_FIELD_TRANSPORT_ID, UNUM_TYPE},
127  {DBA_FIELD_SERVICE_ID, UNUM_TYPE},
128  {DBA_FIELD_VERSION, UNUM_TYPE},
129 
130  {DBA_FIELD_LNB_TYPE, UNUM_TYPE},
131  {DBA_FIELD_LNB_22K, UNUM_TYPE},
132  {DBA_FIELD_LNB_12V, UNUM_TYPE},
133  {DBA_FIELD_LNB_PULSEPOSN, UNUM_TYPE},
134  {DBA_FIELD_LNB_DISPOSN, UNUM_TYPE},
135  {DBA_FIELD_LNB_DISTONE, UNUM_TYPE},
136  {DBA_FIELD_LNB_DISCSWITCH, UNUM_TYPE},
137  {DBA_FIELD_LNB_DISUSWITCH, UNUM_TYPE},
138  {DBA_FIELD_LNB_DISSMATV, UNUM_TYPE},
139  {DBA_FIELD_LNB_DISREPEAT, UNUM_TYPE},
140  {DBA_FIELD_LNB_UNICABLEFREQ, UNUM_TYPE},
141  {DBA_FIELD_LNB_UNICABLECHAN, UNUM_TYPE},
142  {DBA_FIELD_LNB_POWER, UNUM_TYPE},
143  {DBA_FIELD_LNB_NAME, STR_TYPE},
144 
145  {DBA_FIELD_SAT_DISH, UNUM_TYPE},
146  {DBA_FIELD_SAT_LONGWE, UNUM_TYPE},
147  {DBA_FIELD_SAT_LONGPOS, UNUM_TYPE},
148 
149  {DBA_FIELD_TRAN_FREQ, UNUM_TYPE},
150  {DBA_FIELD_TRAN_SRATE, UNUM_TYPE},
151  {DBA_FIELD_TRAN_SIGNAL_STRENGTH, UNUM_TYPE},
152  {DBA_FIELD_TRAN_SIGNAL_QUALITY, UNUM_TYPE},
153 
154  {DBA_FIELD_STRAN_POL, UNUM_TYPE},
155  {DBA_FIELD_STRAN_FEC, UNUM_TYPE},
156  {DBA_FIELD_STRAN_DVBS2, UNUM_TYPE},
157  {DBA_FIELD_STRAN_MODULATION, UNUM_TYPE},
158 
159  {DBA_FIELD_TTRAN_MODE, UNUM_TYPE},
160  {DBA_FIELD_TTRAN_TERR_TYPE, UNUM_TYPE},
161  {DBA_FIELD_TTRAN_PLP_ID, UNUM_TYPE},
162  {DBA_FIELD_TTRAN_BWIDTH, UNUM_TYPE},
163 
164  {DBA_FIELD_CTRAN_MODE, UNUM_TYPE},
165 
166  {DBA_FIELD_SERV_ID, UNUM_TYPE},
167  {DBA_FIELD_SERV_TYPE, UNUM_TYPE},
168  {DBA_FIELD_SERV_LCN, UNUM_TYPE},
169  {DBA_FIELD_SERV_REQ_LCN, UNUM_TYPE},
170  {DBA_FIELD_SERV_HIDDEN, UNUM_TYPE},
171  {DBA_FIELD_SERV_SELECTABLE, UNUM_TYPE},
172  {DBA_FIELD_SERV_LOCKED, UNUM_TYPE},
173  {DBA_FIELD_SERV_SCHED_DISABLED, UNUM_TYPE},
174  {DBA_FIELD_SERV_NOWNEXT_DISABLED, UNUM_TYPE},
175  {DBA_FIELD_SERV_FAV_GROUPS, UNUM_TYPE},
176  {DBA_FIELD_SERV_FREESAT_ID, UNUM_TYPE},
177  {DBA_FIELD_SERV_REGION_ID, UNUM_TYPE},
178  {DBA_FIELD_SERV_LCN_EDITABLE, UNUM_TYPE},
179  {DBA_FIELD_SERV_DELETED, UNUM_TYPE},
180 
181  {DBA_FIELD_TIMER_CRID, STR_TYPE},
182  {DBA_FIELD_TIMER_DISKID, UNUM_TYPE},
183  {DBA_FIELD_TIMER_OTHERCRID, STR_TYPE},
184  {DBA_FIELD_TIMER_HANDLE, UNUM_TYPE},
185  {DBA_FIELD_TIMER_STARTTIME, UNUM_TYPE},
186  {DBA_FIELD_TIMER_DURATION, UNUM_TYPE},
187  {DBA_FIELD_TIMER_TYPE, UNUM_TYPE},
188  {DBA_FIELD_TIMER_FREQUENCY, UNUM_TYPE},
189  {DBA_FIELD_TIMER_RAMPVOLUME, UNUM_TYPE},
190  {DBA_FIELD_TIMER_EVENTID, UNUM_TYPE},
191  {DBA_FIELD_TIMER_MISSED, UNUM_TYPE},
192  {DBA_FIELD_TIMER_EVENT_TRIGGERED, UNUM_TYPE},
193  {DBA_FIELD_TIMER_NOTIFY_TIME, UNUM_TYPE},
194  {DBA_FIELD_TIMER_ADDITIONAL_INFO, STR_TYPE},
195  {DBA_FIELD_TIMER_START_PADDING, UNUM_TYPE},
196  {DBA_FIELD_TIMER_END_PADDING, UNUM_TYPE},
197  {DBA_FIELD_TIMER_DO_NOT_DELETE, UNUM_TYPE},
198 
199  {DBA_FIELD_CRID_SERIES, UNUM_TYPE},
200  {DBA_FIELD_CRID_RECOMMENDED, UNUM_TYPE},
201  {DBA_FIELD_CRID_EIT_DATE, UNUM_TYPE},
202  {DBA_FIELD_CRID_DO_NOT_DELETE, UNUM_TYPE},
203 
204  {DBA_FIELD_FAVLIST_ID, UNUM_TYPE},
205  {DBA_FIELD_FAVLIST_INDEX, UNUM_TYPE},
206  {DBA_FIELD_FAVLIST_USER_DATA, UNUM_TYPE},
207 
208  {DBA_FIELD_BAND_POLARITY, UNUM_TYPE},
209  {DBA_FIELD_BAND_MIN_FREQUENCY, UNUM_TYPE},
210  {DBA_FIELD_BAND_MAX_FREQUENCY, UNUM_TYPE},
211  {DBA_FIELD_BAND_LOCAL_OSC_FREQUENCY, UNUM_TYPE},
212  {DBA_FIELD_BAND_LNB_VOLTAGE, UNUM_TYPE},
213  {DBA_FIELD_BAND_22_KHZ, UNUM_TYPE}
214 };
215 
216 // String fields must start on a byte boundary
217 // String fields MUST be defined in RAM
218 // format is : FIELD NAME, NVM BIT OFFSET, NVM BIT SIZE, RAM BYTE OFFSET, RAM BYTE SIZE, DEFAULT VALUE
219 
220 /* LNB record */
221 static const FIELD_ACCESS nvm_lnb_rec[] =
222 {
223  {DBA_FIELD_LNB_TYPE, 0, 2, 0, 0, 0},
224  {DBA_FIELD_LNB_POWER, 2, 2, 0, 0, 0},
225  {DBA_FIELD_LNB_22K, 4, 1, 0, 0, 0},
226  {DBA_FIELD_LNB_12V, 5, 1, 0, 0, 0},
227  {DBA_FIELD_LNB_PULSEPOSN, 6, 1, 0, 0, 0},
228  {DBA_FIELD_LNB_DISPOSN, 7, 1, 0, 0, 0},
229  {DBA_FIELD_LNB_DISTONE, 8, 2, 0, 0, 0},
230  {DBA_FIELD_LNB_DISCSWITCH, 10, 3, 0, 0, 0},
231  {DBA_FIELD_LNB_DISUSWITCH, 13, 5, 0, 0, 0},
232  {DBA_FIELD_LNB_DISSMATV, 18, 1, 0, 0, 0},
233  {DBA_FIELD_LNB_DISREPEAT, 19, 4, 0, 0, 0},
234  {DBA_FIELD_LNB_UNICABLEFREQ, 23, 32, 0, 0, 0},
235  {DBA_FIELD_LNB_UNICABLECHAN, 55, 3, 0, 0, 0},
236  {DBA_FIELD_LNB_NAME, 64, (DBA_LNB_NAME_LEN * 8), 0, DBA_LNB_NAME_LEN, 0}
237  /* 2 blocks used - 64 bits spare here */
238 };
239 
240 /* LNB band record */
241 static const FIELD_ACCESS nvm_lnb_band_rec[] =
242 {
243  {DBA_FIELD_PARENT, 0, 16, 0, 0, 0},
244  {DBA_FIELD_BAND_POLARITY, 16, 2, 0, 0, 0},
245  {DBA_FIELD_BAND_MIN_FREQUENCY, 18, 16, 0, 0, 0},
246  {DBA_FIELD_BAND_MAX_FREQUENCY, 34, 16, 0, 0, 0},
247  {DBA_FIELD_BAND_LOCAL_OSC_FREQUENCY, 50, 16, 0, 0, 0},
248  {DBA_FIELD_BAND_LNB_VOLTAGE, 66, 2, 0, 0, 0},
249  {DBA_FIELD_BAND_22_KHZ, 68, 1, 0, 0, 0}
250  /* 1 block used - 91 bits spare here */
251 };
252 
253 /* Satellite record */
254 static const FIELD_ACCESS nvm_sat_rec[] =
255 {
256  {DBA_FIELD_PARENT, 0, 16, 0, 0, 0},
257  {DBA_FIELD_SAT_DISH, 16, 16, 0, 0, 0},
258  {DBA_FIELD_SAT_LONGWE, 32, 1, 0, 0, 0},
259  {DBA_FIELD_SAT_LONGPOS, 33, 15, 0, 0, 0},
260  {DBA_FIELD_REC_NAME, 48, (DBA_GROUP_NAME_LEN * 8), 0, DBA_GROUP_NAME_LEN, 0}
261  /* 3 blocks used - 152 bits spare */
262 };
263 
264 /* Network record */
265 static const FIELD_ACCESS nvm_net_rec[] =
266 {
267  {DBA_FIELD_PARENT, 0, 16, 0, 0, 0},
268  {DBA_FIELD_NET_ID, 16, 16, 0, 0, 0},
269  {DBA_FIELD_VERSION, 32, 8, 0, 0, 0},
270  {DBA_FIELD_ORIG_NET_ID, 40, 16, 0, 0, 0},
271  {DBA_FIELD_PROFILE_TYPE, 56, 2, 0, 0, 0},
272  {DBA_FIELD_PROFILE_CAM_ID, 58, 32, 0, 0, 0},
273  {DBA_FIELD_OPERATOR_SEARCH, 90, 1, 0, 0, 0},
274  {DBA_FIELD_OP_SEARCH_DATE, 91, 16, 0, 0, 0},
275  {DBA_FIELD_OP_SEARCH_TIME, 107, 16, 0, 0, 0},
276  {DBA_FIELD_FAVLIST_ID, 123, 8, 0, 0, 0},
277  {DBA_FIELD_REC_NAME, 136, (DBA_GROUP_NAME_LEN * 8), 0, DBA_GROUP_NAME_LEN, 0},
278  {DBA_FIELD_PROFILE_NAME, 136 + (DBA_GROUP_NAME_LEN * 8), DBA_PROFILE_NAME_LEN * 8,
279  DBA_GROUP_NAME_LEN, DBA_PROFILE_NAME_LEN, 0}
280  /* 16 blocks used - 72 bits spare */
281 };
282 
283 /* Satellite transponder record */
284 static const FIELD_ACCESS nvm_stran_rec[] =
285 {
286  {DBA_FIELD_PARENT, 0, 16, 0, 0, 0},
287  {DBA_FIELD_TRAN_FREQ, 16, 32, 0, 0, 0},
288  {DBA_FIELD_TRAN_SRATE, 48, 16, 0, 0, 0},
289  {DBA_FIELD_STRAN_POL, 64, 2, 0, 0, 0},
290  {DBA_FIELD_STRAN_FEC, 66, 3, 0, 0, 0},
291  {DBA_FIELD_TRANSPORT_ID, 69, 16, 0, 0, 0},
292  {DBA_FIELD_ORIG_NET_ID, 85, 16, 0, 0, 0},
293  {DBA_FIELD_STRAN_MODULATION, 101, 2, 0, 0, 0},
294  {DBA_FIELD_STRAN_DVBS2, 103, 1, 0, 0, 0},
295  {DBA_FIELD_TRAN_SIGNAL_STRENGTH, 104, 8, 0, 0, 0},
296  {DBA_FIELD_VERSION, 112, 8, 0, 0, 0},
297  {DBA_FIELD_TRAN_SIGNAL_QUALITY, 120, 8, 0, 0, 0}
298 };
299 
300 /* Terrestrial transport record */
301 static const FIELD_ACCESS nvm_ttran_rec[] =
302 {
303  {DBA_FIELD_PARENT, 0, 16, 0, 0, 0},
304  {DBA_FIELD_TRANSPORT_ID, 16, 16, 0, 0, 0},
305  {DBA_FIELD_ORIG_NET_ID, 32, 16, 0, 0, 0},
306  {DBA_FIELD_TRAN_FREQ, 48, 32, 0, 0, 0},
307  {DBA_FIELD_TTRAN_MODE, 80, 2, 0, 0, 0},
308  {DBA_FIELD_TTRAN_BWIDTH, 82, 3, 0, 0, 0},
309  {DBA_FIELD_TRAN_SIGNAL_STRENGTH, 85, 8, 0, 0, 0},
310  {DBA_FIELD_TTRAN_TERR_TYPE, 93, 2, 0, 0, 0},
311  {DBA_FIELD_TTRAN_PLP_ID, 95, 8, 0, 0, 0},
312  {DBA_FIELD_VERSION, 103, 8, 0, 0, 0},
313  {DBA_FIELD_TRAN_SIGNAL_QUALITY, 111, 8, 0, 0, 0}
314 };
315 
316 /* Cable transport record */
317 static const FIELD_ACCESS nvm_ctran_rec[] =
318 {
319  {DBA_FIELD_PARENT, 0, 16, 0, 0, 0},
320  {DBA_FIELD_TRANSPORT_ID, 16, 16, 0, 0, 0},
321  {DBA_FIELD_ORIG_NET_ID, 32, 16, 0, 0, 0},
322  {DBA_FIELD_TRAN_FREQ, 48, 32, 0, 0, 0},
323  {DBA_FIELD_TRAN_SRATE, 80, 16, 0, 0, 0},
324  {DBA_FIELD_CTRAN_MODE, 96, 3, 0, 0, 0},
325  {DBA_FIELD_TRAN_SIGNAL_STRENGTH, 99, 8, 0, 0, 0},
326  {DBA_FIELD_VERSION, 107, 8, 0, 0, 0},
327  {DBA_FIELD_TRAN_SIGNAL_QUALITY, 115, 8, 0, 0, 0}
328 };
329 
330 /* Service record (used for satellite, cable and terrestrial) */
331 static const FIELD_ACCESS nvm_serv_rec[] =
332 {
333  {DBA_FIELD_PARENT, 0, 16, 0, 0, 0},
334  {DBA_FIELD_SERV_ID, 16, 16, 0, 0, 0},
335  {DBA_FIELD_SERV_TYPE, 46, 8, 0, 0, 0},
336  {DBA_FIELD_SERV_LCN, 32, 14, 0, 0, 0},
337  {DBA_FIELD_SERV_REQ_LCN, 54, 16, 0, 0, 0},
338  {DBA_FIELD_SERV_FAV_GROUPS, 70, 8, 0, 0, 0},
339  {DBA_FIELD_SERV_HIDDEN, 78, 1, 0, 0, 0},
340  {DBA_FIELD_SERV_SELECTABLE, 79, 1, 0, 0, 0},
341  {DBA_FIELD_SERV_LOCKED, 80, 1, 0, 0, 0},
342  {DBA_FIELD_SERV_SCHED_DISABLED, 81, 1, 0, 0, 0},
343  {DBA_FIELD_SERV_NOWNEXT_DISABLED, 82, 1, 0, 0, 0},
344  {DBA_FIELD_SERV_FREESAT_ID, 83, 16, 0, 0, 0},
345  {DBA_FIELD_SERV_REGION_ID, 99, 16, 0, 0, 0},
346  {DBA_FIELD_SERV_LCN_EDITABLE, 115, 1, 0, 0, 0},
347  {DBA_FIELD_SERV_DELETED, 116, 1, 0, 0, 0},
348  {DBA_FIELD_REC_NAME, 120, (DBA_SERV_NAME_LEN * 8), 0, DBA_SERV_NAME_LEN, 0}
349  /* 3 blocks used - 103 bits spare here */
350 };
351 
352 /* Timer record (also used for PVR recording) */
353 static const FIELD_ACCESS nvm_timer_rec[] =
354 {
355  {DBA_FIELD_TIMER_HANDLE, 0, 32, 0, 0, 0},
356  {DBA_FIELD_TIMER_DISKID, 32, 16, 0, 0, 0},
357  {DBA_FIELD_TIMER_EVENTID, 48, 16, 0, 0, 0},
358  {DBA_FIELD_ORIG_NET_ID, 64, 16, 0, 0, 0},
359  {DBA_FIELD_TRANSPORT_ID, 80, 16, 0, 0, 0},
360  {DBA_FIELD_SERVICE_ID, 96, 16, 0, 0, 0},
361  {DBA_FIELD_TIMER_STARTTIME, 112, 32, 0, 0, 0},
362  {DBA_FIELD_TIMER_DURATION, 144, 32, 0, 0, 0},
363  {DBA_FIELD_TIMER_TYPE, 176, 4, 0, 0, 0},
364  {DBA_FIELD_TIMER_FREQUENCY, 180, 4, 0, 0, 0},
365  {DBA_FIELD_TIMER_RAMPVOLUME, 184, 1, 0, 0, 0},
366  {DBA_FIELD_TIMER_MISSED, 185, 1, 0, 0, 0},
367  {DBA_FIELD_CRID_RECOMMENDED, 186, 1, 0, 0, 0},
368  {DBA_FIELD_TIMER_EVENT_TRIGGERED, 187, 1, 0, 0, 0},
369  {DBA_FIELD_TIMER_NOTIFY_TIME, 188, 16, 0, 0, 0},
370  {DBA_FIELD_TIMER_START_PADDING, 204, 32, 0, 0, 0},
371  {DBA_FIELD_TIMER_END_PADDING, 236, 32, 0, 0, 0},
372  {DBA_FIELD_TIMER_DO_NOT_DELETE, 268, 1, 0, 0, 0},
373  {DBA_FIELD_REC_NAME, 272, (DBA_TIMER_NAME_LEN * 8), 0, DBA_TIMER_NAME_LEN, 0},
374  {DBA_FIELD_TIMER_CRID, 272 + (DBA_TIMER_NAME_LEN * 8), (DBA_CRID_LEN * 8),
375  DBA_TIMER_NAME_LEN, DBA_CRID_LEN, 0},
376  {DBA_FIELD_TIMER_OTHERCRID, 272 + (DBA_TIMER_NAME_LEN * 8) + (DBA_CRID_LEN * 8),
377  (DBA_CRID_LEN * 8), DBA_TIMER_NAME_LEN + DBA_CRID_LEN, DBA_CRID_LEN, 0},
378  {DBA_FIELD_TIMER_ADDITIONAL_INFO, 272 + (DBA_TIMER_NAME_LEN * 8) + (DBA_CRID_LEN * 8) + (DBA_CRID_LEN * 8),
379  (DBA_TIMER_ADDINFO_LEN * 8), DBA_TIMER_NAME_LEN + DBA_CRID_LEN + DBA_CRID_LEN, DBA_TIMER_ADDINFO_LEN, 0}
380  /* 34 blocks used - 104 spare bits here */
381 };
382 
383 /* CRID record */
384 static const FIELD_ACCESS nvm_crid_rec[] =
385 {
386  {DBA_FIELD_CRID_EIT_DATE, 0, 16, 0, 0, 0},
387  {DBA_FIELD_TIMER_STARTTIME, 16, 32, 0, 0, 0},
388  {DBA_FIELD_SERVICE_ID, 48, 16, 0, 0, 0},
389  {DBA_FIELD_CRID_SERIES, 64, 1, 0, 0, 0},
390  {DBA_FIELD_CRID_RECOMMENDED, 65, 1, 0, 0, 0},
391  {DBA_FIELD_CRID_DO_NOT_DELETE, 66, 1, 0, 0, 0},
392  {DBA_FIELD_REC_NAME, 72, (DBA_TIMER_NAME_LEN * 8), 0, DBA_TIMER_NAME_LEN, 0},
393  {DBA_FIELD_TIMER_CRID, 72 + (DBA_TIMER_NAME_LEN * 8), (DBA_CRID_LEN * 8),
394  DBA_TIMER_NAME_LEN, DBA_CRID_LEN, 0}
395  /* 17 blocks used - 88 spare bits */
396 };
397 
398 /* Favourite list record */
399 static const FIELD_ACCESS nvm_fav_list_rec[] =
400 {
401  {DBA_FIELD_FAVLIST_ID, 0, 8, 0, 0, 0},
402  {DBA_FIELD_FAVLIST_INDEX, 8, 8, 0, 0, 0},
403  {DBA_FIELD_FAVLIST_USER_DATA, 16, 32, 0, 0, 0},
404  {DBA_FIELD_REC_NAME, 48, (DBA_FAVLIST_NAME_LEN * 8), 0, DBA_FAVLIST_NAME_LEN, 0}
405  /* 7 blocks used - 48 spare bits */
406 };
407 
408 /* Favourite list service record */
409 static const FIELD_ACCESS nvm_fav_serv_rec[] =
410 {
411  {DBA_FIELD_PARENT, 0, 16, 0, 0, 0}, /* This is used to link to the service */
412  {DBA_FIELD_FAVLIST_ID, 16, 8, 0, 0, 0},
413  {DBA_FIELD_FAVLIST_INDEX, 24, 16, 0, 0, 0}
414  /* 1 block used - 120 spare bits */
415 };
416 
417 static const FIELD_ACCESS nvm_cicam_timer[] =
418 {
419  {DBA_FIELD_PROFILE_CAM_ID, 0, 32, 0, 0, 0},
420  {DBA_FIELD_TIMER_HANDLE, 32, 32, 0, 0, 0}
421  /* 1 block used - 96 spare bits */
422 };
423 
424 /* Event record - not stored in this database */
425 /* static const FIELD_ACCESS nvm_event_rec[0]; */
426 
427 static const RECORD_ACCESS database_access_lut[DBA_NUM_RECORDS] =
428 {
429  {NUM_FIELDS(nvm_lnb_rec), nvm_lnb_rec},
430  {NUM_FIELDS(nvm_sat_rec), nvm_sat_rec},
431  {NUM_FIELDS(nvm_net_rec), nvm_net_rec},
432  {NUM_FIELDS(nvm_stran_rec), nvm_stran_rec},
433  {NUM_FIELDS(nvm_ttran_rec), nvm_ttran_rec},
434  {NUM_FIELDS(nvm_ctran_rec), nvm_ctran_rec},
435  {NUM_FIELDS(nvm_serv_rec), nvm_serv_rec},
436  {NUM_FIELDS(nvm_timer_rec), nvm_timer_rec},
437  {NUM_FIELDS(nvm_crid_rec), nvm_crid_rec},
438  {NUM_FIELDS(nvm_fav_list_rec), nvm_fav_list_rec},
439  {NUM_FIELDS(nvm_fav_serv_rec), nvm_fav_serv_rec},
440  {NUM_FIELDS(nvm_lnb_band_rec), nvm_lnb_band_rec},
441  {NUM_FIELDS(nvm_cicam_timer), nvm_cicam_timer}/*,
442  {NUM_FIELDS(nvm_event_rec), nvm_event_rec}*/
443 };
444 
445 static BOOLEAN dba_initialised = FALSE;
446 static void *dba_sem;
447 static U8BIT version_string[FORMAT_ID_STRING_SIZE + 1];
448 
449 static U8BIT *backup_database;
450 
451 //---local function prototypes for this file--------------------------------------------------------
452 // (internal functions declared static to make them local)
453 static BOOLEAN ReadFormat(U8BIT *data_ptr, U8BIT *version);
454 static void WriteFormat(U8BIT *data_ptr);
455 static void BuildDatabase(U8BIT *data_ptr);
456 static void ConvertDatabase(U8BIT *data_ptr);
457 static void ClearDatabase(void);
458 
459 static U8BIT GetFieldType(U16BIT field_id);
460 static U16BIT GetNVMRecSize(U8BIT rec_id);
461 static U16BIT GetRAMRecSize(U8BIT rec_id);
462 
463 static BOOLEAN GetNVMFieldParams(U8BIT rec_id, U16BIT field_id, U16BIT *offset, U16BIT *size);
464 static BOOLEAN GetRAMFieldParams(U8BIT rec_id, U16BIT field_id, U16BIT *offset, U16BIT *size);
465 
466 static void AddToNVMList(void *rec_ptr);
467 static void SetStartNVMList(U8BIT rec_id, U16BIT block_no);
468 static U16BIT GetStartNVMList(U8BIT *data_ptr, U8BIT rec_id);
469 static void RemoveFromNVMList(void *rec_ptr);
470 
471 static void DestroyRecord(void *rec_ptr);
472 
473 
474 //--------------------------------------------------------------------------------------------------
475 // global function definitions
476 //--------------------------------------------------------------------------------------------------
477 
482 BOOLEAN DBA_Initialise(void)
483 {
484  FUNCTION_START(DBA_Initialise);
485 
486  if (!dba_initialised)
487  {
488  dba_sem = STB_OSCreateSemaphore();
489  if (dba_sem != NULL)
490  {
491  dba_initialised = TRUE;
492  }
493 
495 
496  backup_database = NULL;
497  }
498 
499  FUNCTION_FINISH(DBA_Initialise);
500 
501  return(dba_initialised);
502 }
503 
508 void DBA_Terminate(void)
509 {
510  FUNCTION_START(DBA_Terminate);
511 
512  if (dba_initialised)
513  {
514  if (dba_sem != NULL)
515  {
516  STB_OSDeleteSemaphore(dba_sem);
517  dba_sem = NULL;
518  }
519 
520  if (backup_database != NULL)
521  {
522  STB_FreeMemory(backup_database);
523  backup_database = NULL;
524  }
525 
526  dba_initialised = FALSE;
527  }
528 
529  FUNCTION_FINISH(DBA_Terminate);
530 }
531 
541 BOOLEAN DBA_LoadDatabase(U8BIT *pathname)
542 {
543  U32BIT fsize;
544  U16BIT i, j, k;
545  U8BIT *ram_cache;
546  U8BIT version;
547  BOOLEAN retval;
548 
549  FUNCTION_START(DBA_LoadDatabase);
550 
551  /* pathname isn't used for NVM database */
552  USE_UNWANTED_PARAM(pathname);
553 
554  retval = FALSE;
555 
556  if (dba_initialised)
557  {
558  /* Calc format size */
559  fsize = (U16BIT)sizeof(DATABASE_FORMAT);
560  fsize += (U16BIT)sizeof(DATABASE_DESCRIPTOR);
561 
562  for (i = 0; i < DBA_NUM_RECORDS; i++)
563  {
564  k = 0;
565  for (j = 0; j < database_access_lut[i].num_fields; j++)
566  {
567  if (database_access_lut[i].field[j].nvm_bit_size > 0)
568  {
569  k++;
570  fsize += (U16BIT)sizeof(FIELD_DESCRIPTOR);
571  }
572  }
573 
574  if (k > 0)
575  {
576  fsize += (U16BIT)sizeof(RECORD_DESCRIPTOR);
577  }
578  }
579 
580  /* Initialise DB access */
581  STB_InitNVMAccess(fsize);
583 
584  fsize = STB_NVMGetSTBSize();
585 
586  /* Only want to setup a RAM area for the DB if one isn't currently setup */
587  if ((ram_cache = STB_GetNVMAccessRAM()) == NULL)
588  {
589  /* Allocate RAM that can be used as a cache by the database */
590  ram_cache = (U8BIT *)STB_GetMemory(fsize);
591  }
592 
593  if (ram_cache != NULL)
594  {
595  if (STB_NVMSTBRead(0, STB_NVMGetSTBSize(), ram_cache))
596  {
597  /* Validate database */
598  if (ReadFormat(ram_cache, &version))
599  {
600  /* Valid - check format version */
601  if (version == FORMAT_VERSION_NUM)
602  {
603  /* Correct format - make sure checksums are correct */
605  {
606  /* Correct format - build RAM database */
607  BuildDatabase(ram_cache);
608  }
609  else
610  {
611  /* Block checksums aren't correct - use an empty database */
612  memset(ram_cache, 0xff, fsize);
613 
614  WriteFormat(ram_cache);
615  ClearDatabase();
616  BuildDatabase(ram_cache);
617  STB_NVMSTBWrite(0, STB_NVMGetSTBSize(), ram_cache);
618  }
619  }
620  else
621  {
622  /* Wrong format - convert, build and save RAM database */
623  ConvertDatabase(ram_cache);
624  BuildDatabase(ram_cache);
625  STB_NVMSTBWrite(0, STB_NVMGetSTBSize(), ram_cache);
626  }
627  }
628  else
629  {
630  /* Invalid - use an empty database */
631  memset(ram_cache, 0xff, fsize);
632 
633  WriteFormat(ram_cache);
634  ClearDatabase();
635  BuildDatabase(ram_cache);
636  STB_NVMSTBWrite(0, STB_NVMGetSTBSize(), ram_cache);
637  }
638 
639  /* Use the data in memory as a ram cache for the database */
640  STB_SetNVMAccessRAM(ram_cache);
641 
642  retval = TRUE;
643  }
644  else
645  {
646  /* Failed to read database, maybe the wrong size, so create an empty one */
647  memset(ram_cache, 0xff, fsize);
648 
649  WriteFormat(ram_cache);
650  ClearDatabase();
651  BuildDatabase(ram_cache);
652  STB_NVMSTBWrite(0, STB_NVMGetSTBSize(), ram_cache);
653  }
654  }
655  }
656 
657  FUNCTION_FINISH(DBA_LoadDatabase);
658 
659  return(retval);
660 }
661 
667 BOOLEAN DBA_SaveDatabase(void)
668 {
669  BOOLEAN retval;
670 
671  FUNCTION_START(DBA_SaveDatabase);
672 
673  if (dba_initialised)
674  {
675  STB_NVMSave();
676  retval = TRUE;
677  }
678  else
679  {
680  retval = FALSE;
681  }
682 
683  FUNCTION_FINISH(DBA_SaveDatabase);
684 
685  return(retval);
686 }
687 
694 BOOLEAN DBA_ClearDatabase(void)
695 {
696  BOOLEAN retval;
697 
698  FUNCTION_START(DBA_ClearDatabase);
699 
700  if (dba_initialised)
701  {
702  ClearDatabase();
703  retval = TRUE;
704  }
705  else
706  {
707  retval = FALSE;
708  }
709 
710  FUNCTION_FINISH(DBA_ClearDatabase);
711 
712  return(retval);
713 }
714 
723 BOOLEAN DBA_BackupDatabase(U8BIT *pathname)
724 {
725  BOOLEAN retval;
726  U32BIT db_size;
727  U8BIT *current_db;
728 
729  FUNCTION_START(DBA_BackupDatabase);
730 
731  /* pathname isn't used for NVM database */
732  USE_UNWANTED_PARAM(pathname);
733 
734  retval = FALSE;
735 
736  if (backup_database != NULL)
737  {
738  /* Already have a backup, delete it first */
739  STB_FreeMemory(backup_database);
740  backup_database = NULL;
741  }
742 
743  /* Only backup if there's a current database */
744  if ((current_db = STB_GetNVMAccessRAM()) != NULL)
745  {
746  STB_NVMFlushCache(FALSE);
747 
748  /* Allocate memory to backup to */
749  db_size = STB_NVMGetSTBSize();
750  if ((backup_database = (U8BIT *)STB_GetMemory(db_size)) != NULL)
751  {
752  memcpy(backup_database, current_db, db_size);
753  retval = TRUE;
754  }
755  }
756 
757  FUNCTION_FINISH(DBA_BackupDatabase);
758 
759  return(retval);
760 }
761 
767 {
768  BOOLEAN retval = FALSE;
769  U8BIT *current_db;
770 
771  FUNCTION_START(DBA_CanRestoreDatabase);
772 
773  current_db = STB_GetNVMAccessRAM();
774 
775  if ((backup_database != NULL) && (current_db != NULL))
776  {
777  retval = TRUE;
778  }
779 
780  FUNCTION_FINISH(DBA_CanRestoreDatabase);
781 
782  return(retval);
783 }
784 
789 BOOLEAN DBA_RestoreDatabase(void)
790 {
791  BOOLEAN retval = FALSE;
792  U32BIT db_size;
793  U8BIT *current_db;
794 
795  FUNCTION_START(DBA_RestoreDatabase);
796 
797  current_db = STB_GetNVMAccessRAM();
798 
799  if ((backup_database != NULL) && (current_db != NULL))
800  {
801  STB_NVMFlushCache(TRUE);
802 
803  /* Overwrite the existing RAM cache database with the backup copy */
804  db_size = STB_NVMGetSTBSize();
805  memcpy(current_db, backup_database, db_size);
806 
807  /* Force the database status to ensure it's saved the next time STB_NVMSave is called */
808  STB_NVMChanged(TRUE);
809 
810  retval = TRUE;
811  }
812 
813  FUNCTION_FINISH(DBA_RestoreDatabase);
814 
815  return(retval);
816 }
817 
823 {
824  FUNCTION_START(DBA_EraseBackupDatabase);
825 
826  if (backup_database != NULL)
827  {
828  STB_FreeMemory(backup_database);
829  backup_database = NULL;
830  }
831 
832  FUNCTION_FINISH(DBA_EraseBackupDatabase);
833 }
834 
840 BOOLEAN DBA_ExportToXML(U8BIT *xml_pathname)
841 {
842  FUNCTION_START(DBA_ExportToXML);
843  USE_UNWANTED_PARAM(xml_pathname);
844  FUNCTION_FINISH(DBA_ExportToXML);
845  return(FALSE);
846 }
847 
855 BOOLEAN DBA_ImportFromXML(U8BIT *xml_pathname)
856 {
857  FUNCTION_START(DBA_ImportFromXML);
858  USE_UNWANTED_PARAM(xml_pathname);
859  FUNCTION_FINISH(DBA_ImportFromXML);
860  return(FALSE);
861 }
862 
867 {
868  FUNCTION_START(DBA_LockDatabase);
869  STB_OSSemaphoreWait(dba_sem);
870  FUNCTION_FINISH(DBA_LockDatabase);
871 }
872 
877 {
878  FUNCTION_START(DBA_UnlockDatabase);
879  STB_OSSemaphoreSignal(dba_sem);
880  FUNCTION_FINISH(DBA_UnlockDatabase);
881 }
882 
888 {
889  DATABASE_FORMAT db_format;
890 
891  FUNCTION_START(DBA_DatabaseVersion);
892 
893  /* Read format header */
894  if (STB_ReadNVMData(0, sizeof(DATABASE_FORMAT), (U8BIT *)&db_format))
895  {
896  /* Copy version string into static array */
897  strncpy((char *)version_string, (char *)db_format.id_str, FORMAT_ID_STRING_SIZE + 1);
898  }
899  else
900  {
901  version_string[0] = '\0';
902  }
903 
904  FUNCTION_FINISH(DBA_DatabaseVersion);
905 
906  return(version_string);
907 }
908 
915 U32BIT DBA_DatabaseFileSize(U32BIT *max_size)
916 {
917  U32BIT size;
918 
919  FUNCTION_START(DBA_DatabaseFileSize);
920 
922 
923  if (max_size != NULL)
924  {
925  *max_size = STB_GetNVMBlockCount() * STB_GetNVMBlockSize();
926  }
927 
928  FUNCTION_FINISH(DBA_DatabaseFileSize);
929 
930  return(size);
931 }
932 
940 void* DBA_CreateRecord(U32BIT record_id, void *parent)
941 {
942  U16BIT nvm_size, ram_size, nvm_block;
943  U16BIT field_offset, field_size;
944  void *rec_ptr;
945 
946  FUNCTION_START(DBA_CreateRecord);
947 
948  rec_ptr = NULL;
949 
950  if (dba_initialised && (record_id < DBA_NUM_RECORDS) /*&& (record_id != DBA_RECORD_EVENT)*/)
951  {
952  nvm_size = GetNVMRecSize(record_id);
953  ram_size = GetRAMRecSize(record_id);
954 
955  /* If record has an NVM record */
956  if (nvm_size > 0)
957  {
958  /* Try to create NVM record */
959  nvm_block = STB_CreateNVMRecord(record_id, nvm_size);
960  if (nvm_block != NVM_INVALID_BLOCK_ID)
961  {
962  /* Try to create RAM record */
963  rec_ptr = STB_CreateRAMRecord(record_id, ram_size, nvm_block, parent);
964  if (rec_ptr == NULL)
965  {
966  /* Failed - destroy NVM record */
967  STB_DestroyNVMRecord(nvm_block);
968  }
969  else
970  {
971  /* Add to linked list */
972  AddToNVMList(rec_ptr);
973 
974  if (parent != NULL)
975  {
976  /* Set parent link */
977  if (GetNVMFieldParams(record_id, DBA_FIELD_PARENT, &field_offset,
978  &field_size))
979  {
980  STB_SetNVMRecordNumber(nvm_block, field_offset, field_size,
981  (U32BIT)STB_GetRAMRecordNVMBlock(parent));
982  }
983  }
984  else
985  {
986  if (GetNVMFieldParams(record_id, DBA_FIELD_PARENT, &field_offset,
987  &field_size))
988  {
989  STB_SetNVMRecordNumber(nvm_block, field_offset, field_size,
990  NVM_INVALID_BLOCK_ID);
991  }
992  }
993  }
994  }
995  }
996  else
997  {
998  /* Only a RAM record - try to create it */
999  rec_ptr = STB_CreateRAMRecord(record_id, ram_size, NVM_INVALID_BLOCK_ID, parent);
1000  }
1001  }
1002 
1003  FUNCTION_FINISH(DBA_CreateRecord);
1004 
1005  return(rec_ptr);
1006 }
1007 
1013 void DBA_DestroyRecord(void *record)
1014 {
1015  U8BIT count;
1016  void *crec_ptr;
1017  void *cnext_ptr;
1018 
1019  FUNCTION_START(DBA_DestroyRecord);
1020 
1021  if (dba_initialised && (record != NULL))
1022  {
1023  /* Destroy any children of this record */
1024  count = DBA_NUM_RECORDS - 1;
1025  while (count > STB_GetRAMRecordId(record))
1026  {
1027  crec_ptr = STB_FindRAMRecordFromId(count, record, NULL);
1028  while (crec_ptr != NULL)
1029  {
1030  cnext_ptr = STB_FindRAMRecordFromId(count, record, crec_ptr);
1031  DestroyRecord(crec_ptr);
1032  crec_ptr = cnext_ptr;
1033  }
1034 
1035  count--;
1036  }
1037 
1038  /* Destroy the record */
1039  DestroyRecord(record);
1040  }
1041 
1042  FUNCTION_FINISH(DBA_DestroyRecord);
1043 }
1044 
1055 void* DBA_FindRecord(U32BIT record_id, void *parent, void *last_rec)
1056 {
1057  void *rec_ptr;
1058 
1059  FUNCTION_START(DBA_FindRecord);
1060 
1061  if (dba_initialised && (record_id < DBA_NUM_RECORDS))
1062  {
1063  rec_ptr = STB_FindRAMRecordFromId(record_id, parent, last_rec);
1064  }
1065  else
1066  {
1067  rec_ptr = NULL;
1068  }
1069 
1070  FUNCTION_FINISH(DBA_FindRecord);
1071 
1072  return(rec_ptr);
1073 }
1074 
1080 void DBA_SetRecordParent(void *record, void *parent)
1081 {
1082  U8BIT rec_id;
1083  U16BIT nvm_block;
1084  U32BIT link_val;
1085  U16BIT field_offset, field_size;
1086 
1087  FUNCTION_START(DBA_SetRecordParent);
1088 
1089  ASSERT(record != NULL);
1090 
1091  if (dba_initialised && (record != NULL))
1092  {
1093  /* Get record id of record */
1094  rec_id = STB_GetRAMRecordId(record);
1095 
1096  /* Set parent pointer in RAM record */
1097  STB_SetRAMRecordParent(record, parent);
1098 
1099  /* Save NVM parent link... */
1100  if (parent == NULL)
1101  {
1102  link_val = NVM_INVALID_BLOCK_ID;
1103  }
1104  else
1105  {
1106  link_val = (U32BIT)STB_GetRAMRecordNVMBlock(parent);
1107  }
1108 
1109  if (GetRAMFieldParams(rec_id, DBA_FIELD_PARENT, &field_offset, &field_size))
1110  {
1111  STB_SetRAMRecordNumber(record, field_offset, field_size, link_val);
1112  }
1113 
1114  if (GetNVMFieldParams(rec_id, DBA_FIELD_PARENT, &field_offset, &field_size))
1115  {
1116  nvm_block = STB_GetRAMRecordNVMBlock(record);
1117  STB_SetNVMRecordNumber(nvm_block, field_offset, field_size, link_val);
1118  }
1119  }
1120 
1121  FUNCTION_FINISH(DBA_SetRecordParent);
1122 }
1123 
1129 void* DBA_GetRecordParent(void *record)
1130 {
1131  void *parent;
1132 
1133  FUNCTION_START(DBA_GetRecordParent);
1134 
1135  ASSERT(record != NULL);
1136 
1137  if (dba_initialised && (record != NULL))
1138  {
1139  parent = STB_GetRAMRecordParent(record);
1140  }
1141  else
1142  {
1143  parent = NULL;
1144  }
1145 
1146  FUNCTION_FINISH(DBA_GetRecordParent);
1147 
1148  return(parent);
1149 }
1150 
1157 void DBA_SaveRecord(void *record)
1158 {
1159  FUNCTION_START(DBA_SaveRecord);
1160 
1161  /* Not implemented for NVM storage */
1162  USE_UNWANTED_PARAM(record);
1163 
1164  FUNCTION_FINISH(DBA_SaveRecord);
1165 }
1166 
1175 BOOLEAN DBA_SetFieldValue(void *record, U32BIT field_id, U32BIT value)
1176 {
1177  U8BIT rec_id, type;
1178  U16BIT field_size, field_offset;
1179  BOOLEAN retval;
1180 
1181  FUNCTION_START(DBA_SetFieldValue);
1182 
1183  ASSERT(record != NULL);
1184 
1185  retval = FALSE;
1186 
1187  if (dba_initialised)
1188  {
1189  /* Get record id of record and look for field id */
1190  rec_id = STB_GetRAMRecordId(record);
1191  type = GetFieldType(field_id);
1192  if (type != STR_TYPE)
1193  {
1194  /* Check if this field is in RAM */
1195  if (GetRAMFieldParams(rec_id, field_id, &field_offset, &field_size))
1196  {
1197  STB_SetRAMRecordNumber(record, field_offset, field_size, value);
1198  }
1199 
1200  /* Check if this field is in NVM */
1201  if (GetNVMFieldParams(rec_id, field_id, &field_offset, &field_size))
1202  {
1203  STB_SetNVMRecordNumber(STB_GetRAMRecordNVMBlock(record), field_offset,
1204  field_size, value);
1205  }
1206 
1207  retval = TRUE;
1208  }
1209  }
1210 
1211  FUNCTION_FINISH(DBA_SetFieldValue);
1212 
1213  return(retval);
1214 }
1215 
1227 BOOLEAN DBA_SetFieldString(void *record, U32BIT field_id, U8BIT *string, U16BIT num_bytes)
1228 {
1229  U8BIT rec_id, type;
1230  U16BIT field_size, field_offset;
1231  BOOLEAN retval;
1232 
1233  FUNCTION_START(DBA_SetFieldString);
1234 
1235  ASSERT(record != NULL);
1236 
1237  retval = FALSE;
1238 
1239  if (dba_initialised)
1240  {
1241  /* Get record id of record and look for field id */
1242  rec_id = STB_GetRAMRecordId(record);
1243  type = GetFieldType(field_id);
1244  if (type == STR_TYPE)
1245  {
1246  /* Check if this field is in RAM */
1247  if (GetRAMFieldParams(rec_id, field_id, &field_offset, &field_size))
1248  {
1249  if (num_bytes < field_size)
1250  {
1251  field_size = num_bytes;
1252  }
1253 
1254  STB_SetRAMRecordString(record, field_offset, field_size, string);
1255  }
1256 
1257  /* Check if this field is in NVM */
1258  if (GetNVMFieldParams(rec_id, field_id, &field_offset, &field_size))
1259  {
1260  /* NVM field size is in bits, hence *8 */
1261  if ((num_bytes * 8) < field_size)
1262  {
1263  field_size = num_bytes * 8;
1264  }
1265 
1266  STB_SetNVMRecordString(STB_GetRAMRecordNVMBlock(record), field_offset,
1267  field_size, string);
1268  }
1269 
1270  retval = TRUE;
1271  }
1272  }
1273 
1274  FUNCTION_FINISH(DBA_SetFieldString);
1275 
1276  return(retval);
1277 }
1278 
1291 BOOLEAN DBA_SetFieldLangString(void *record, U32BIT field_id, U32BIT lang_code, U8BIT *string,
1292  U16BIT num_bytes)
1293 {
1294  FUNCTION_START(DBA_SetFieldLangString);
1295 
1296  /* Not implemented for NVM storage */
1297  USE_UNWANTED_PARAM(record);
1298  USE_UNWANTED_PARAM(field_id);
1299  USE_UNWANTED_PARAM(lang_code);
1300  USE_UNWANTED_PARAM(string);
1301  USE_UNWANTED_PARAM(num_bytes);
1302 
1303  FUNCTION_FINISH(DBA_SetFieldLangString);
1304 
1305  return(FALSE);
1306 }
1307 
1318 BOOLEAN DBA_SetFieldData(void *record, U32BIT field_id, U8BIT *data, U16BIT num_bytes)
1319 {
1320  FUNCTION_START(DBA_SetFieldData);
1321 
1322  /* Not implemented for NVM storage */
1323  USE_UNWANTED_PARAM(record);
1324  USE_UNWANTED_PARAM(field_id);
1325  USE_UNWANTED_PARAM(data);
1326  USE_UNWANTED_PARAM(num_bytes);
1327 
1328  FUNCTION_FINISH(DBA_SetFieldData);
1329 
1330  return(FALSE);
1331 }
1332 
1341 BOOLEAN DBA_GetFieldValue(void *record, U32BIT field_id, U32BIT *value)
1342 {
1343  U8BIT rec_id, type;
1344  U16BIT field_size, field_offset;
1345  BOOLEAN retval;
1346 
1347  FUNCTION_START(DBA_GetFieldValue);
1348 
1349  ASSERT(record != NULL);
1350  ASSERT(value != NULL);
1351 
1352  retval = FALSE;
1353 
1354  if (dba_initialised)
1355  {
1356  /* Get record id of record and look for field id */
1357  rec_id = STB_GetRAMRecordId(record);
1358  type = GetFieldType(field_id);
1359  if (type != STR_TYPE)
1360  {
1361  /* Check if this field is in RAM */
1362  if (GetRAMFieldParams(rec_id, field_id, &field_offset, &field_size))
1363  {
1364  *value = STB_GetRAMRecordNumber(record, field_offset, field_size);
1365  retval = TRUE;
1366  }
1367  else
1368  {
1369  /* Check if this field is in NVM */
1370  if (GetNVMFieldParams(rec_id, field_id, &field_offset, &field_size))
1371  {
1372  *value = STB_GetNVMRecordNumber(STB_GetRAMRecordNVMBlock(record), field_offset,
1373  field_size);
1374  retval = TRUE;
1375  }
1376  else
1377  {
1378  *value = 0;
1379  }
1380  }
1381  }
1382  }
1383 
1384  FUNCTION_FINISH(DBA_GetFieldValue);
1385 
1386  return(retval);
1387 }
1388 
1400 BOOLEAN DBA_GetFieldString(void *record, U32BIT field_id, U8BIT **string, U16BIT *num_bytes)
1401 {
1402  U8BIT rec_id, type;
1403  U16BIT field_size, field_offset;
1404  BOOLEAN retval;
1405 
1406  FUNCTION_START(DBA_GetFieldString);
1407 
1408  ASSERT(record != NULL);
1409 
1410  retval = FALSE;
1411 
1412  if (dba_initialised)
1413  {
1414  /* Get record id of record and look for field id */
1415  rec_id = STB_GetRAMRecordId(record);
1416  type = GetFieldType(field_id);
1417  if (type == STR_TYPE)
1418  {
1419  /* Check if this field is in RAM */
1420  if (GetRAMFieldParams(rec_id, field_id, &field_offset, &field_size))
1421  {
1422  *string = STB_GetRAMRecordString(record, field_offset, field_size);
1423  retval = TRUE;
1424  }
1425  else
1426  {
1427  /* Check if this field is in NVM */
1428  if (GetNVMFieldParams(rec_id, field_id, &field_offset, &field_size))
1429  {
1431  field_offset, field_size);
1432  retval = TRUE;
1433  }
1434  }
1435 
1436  if (*string != NULL)
1437  {
1438  *num_bytes = STB_GetNumBytesInString(*string);
1439  }
1440  }
1441  }
1442 
1443  FUNCTION_FINISH(DBA_GetFieldString);
1444 
1445  return(retval);
1446 }
1447 
1460 BOOLEAN DBA_GetFieldLangString(void *record, U32BIT field_id, U32BIT lang_code, U8BIT **string,
1461  U16BIT *num_bytes)
1462 {
1463  FUNCTION_START(DBA_GetFieldLangString);
1464 
1465  /* Not implemented for NVM storage */
1466  USE_UNWANTED_PARAM(record);
1467  USE_UNWANTED_PARAM(field_id);
1468  USE_UNWANTED_PARAM(lang_code);
1469  USE_UNWANTED_PARAM(string);
1470  USE_UNWANTED_PARAM(num_bytes);
1471 
1472  FUNCTION_FINISH(DBA_GetFieldLangString);
1473 
1474  return(FALSE);
1475 }
1476 
1488 BOOLEAN DBA_GetFieldData(void *record, U32BIT field_id, U8BIT **data, U16BIT *num_bytes)
1489 {
1490  FUNCTION_START(DBA_GetFieldData);
1491 
1492  /* Not implemented for NVM storage */
1493  USE_UNWANTED_PARAM(record);
1494  USE_UNWANTED_PARAM(field_id);
1495  USE_UNWANTED_PARAM(data);
1496  USE_UNWANTED_PARAM(num_bytes);
1497 
1498  FUNCTION_FINISH(DBA_GetFieldData);
1499 
1500  return(FALSE);
1501 }
1502 
1508 U32BIT DBA_DataBlockSize(U32BIT data_block_id)
1509 {
1510  U32BIT size;
1511 
1512  FUNCTION_START(DBA_DataBlockSize);
1513 
1514  size = STB_NVMGetDataBlockSize(data_block_id);
1515 
1516  FUNCTION_FINISH(DBA_DataBlockSize);
1517 
1518  return(size);
1519 }
1520 
1528 U32BIT DBA_DataBlockRead(U32BIT data_block_id, U8BIT *data, U32BIT num_bytes)
1529 {
1530  U32BIT bytes_read;
1531  U32BIT block_size;
1532 
1533  FUNCTION_START(DBA_DataBlockRead);
1534 
1535  bytes_read = 0;
1536 
1537  block_size = STB_NVMGetDataBlockSize(data_block_id);
1538  if (block_size < num_bytes)
1539  {
1540  num_bytes = block_size;
1541  }
1542 
1543  if (STB_NVMDataBlockRead(data_block_id, num_bytes, data))
1544  {
1545  bytes_read = num_bytes;
1546  }
1547 
1548  FUNCTION_FINISH(DBA_DataBlockRead);
1549 
1550  return(bytes_read);
1551 }
1552 
1560 BOOLEAN DBA_DataBlockWrite(U32BIT data_block_id, U8BIT *data, U32BIT num_bytes)
1561 {
1562  BOOLEAN retval;
1563 
1564  FUNCTION_START(DBA_DataBlockWrite);
1565 
1566  retval = STB_NVMDataBlockWrite(data_block_id, num_bytes, data);;
1567 
1568  FUNCTION_FINISH(DBA_DataBlockWrite);
1569 
1570  return(retval);
1571 }
1572 
1573 //--------------------------------------------------------------------------------------------------
1574 // local function definitions
1575 //--------------------------------------------------------------------------------------------------
1576 
1577 static BOOLEAN ReadFormat(U8BIT *data_ptr, U8BIT *version)
1578 {
1579  DATABASE_FORMAT db_format;
1580  BOOLEAN retval = FALSE;
1581 
1582  FUNCTION_START(ReadFormat);
1583 
1584  // read format header
1585  memcpy((void *)&db_format, (void *)data_ptr, (size_t)sizeof(DATABASE_FORMAT));
1586 
1587  // validate checksum
1588  if (STB_CheckChecksum((U8BIT *)&db_format, (U32BIT)sizeof(DATABASE_FORMAT)))
1589  {
1590  // validate format string
1591  if (strcmp((char *)db_format.id_str, (char *)FORMAT_ID_STRING) == 0)
1592  {
1593  // return version number
1594  *version = db_format.version;
1595  retval = TRUE;
1596  }
1597  }
1598 
1599  FUNCTION_FINISH(ReadFormat);
1600 
1601  return(retval);
1602 }
1603 
1604 static void WriteFormat(U8BIT *data_ptr)
1605 {
1606  U8BIT i, j, rcount;
1607  U8BIT fcount[DBA_NUM_RECORDS];
1608  U16BIT size;
1609  DATABASE_FORMAT db_format;
1610  DATABASE_DESCRIPTOR db_desc;
1611  RECORD_DESCRIPTOR rec_desc;
1612  FIELD_DESCRIPTOR fld_desc;
1613 
1614  FUNCTION_START(WriteFormat);
1615 
1616  // calc num of recs in NVM, number of NVM fields for each record and total descriptor size
1617  rcount = 0;
1618  size = (U16BIT)sizeof(DATABASE_DESCRIPTOR);
1619  for (i = 0; i < DBA_NUM_RECORDS; i++)
1620  {
1621  fcount[i] = 0;
1622  for (j = 0; j < database_access_lut[i].num_fields; j++)
1623  {
1624  if (database_access_lut[i].field[j].nvm_bit_size > 0)
1625  {
1626  fcount[i]++;
1627  size += (U16BIT)sizeof(FIELD_DESCRIPTOR);
1628  }
1629  }
1630  if (fcount[i] > 0)
1631  {
1632  rcount++;
1633  size += (U16BIT)sizeof(RECORD_DESCRIPTOR);
1634  }
1635  }
1636 
1637  // write format header
1638  memset(&db_format, 0, sizeof(db_format));
1639  strncpy((char *)db_format.id_str, (char *)FORMAT_ID_STRING, FORMAT_ID_STRING_SIZE);
1640  db_format.version = FORMAT_VERSION_NUM;
1641  db_format.checksum = STB_CalcChecksum((U8BIT *)&db_format, (U32BIT)sizeof(DATABASE_FORMAT));
1642  memcpy((void *)data_ptr, (void *)&db_format, (size_t)sizeof(DATABASE_FORMAT));
1643  data_ptr += (U16BIT)sizeof(DATABASE_FORMAT);
1644 
1645  // write database descriptor
1646  // endian independent version of:
1647  // db_desc.desc_size = size;
1648  STB_SetBE16Bit(&db_desc.desc_size, size);
1649  db_desc.num_records = rcount;
1650  db_desc.padding[0] = 0;
1651  memcpy((void *)data_ptr, (void *)&db_desc, (size_t)sizeof(DATABASE_DESCRIPTOR));
1652  data_ptr += (U16BIT)sizeof(DATABASE_DESCRIPTOR);
1653 
1654  // write record and field descriptors
1655  for (i = 0; i < DBA_NUM_RECORDS; i++)
1656  {
1657  // if this record has NVM fields
1658  if (fcount[i] > 0)
1659  {
1660  rec_desc.record_id = i;
1661  rec_desc.num_fields = fcount[i];
1662  // endian independent version of:
1663  // rec_desc.first_block = NVM_INVALID_BLOCK_ID;
1664  STB_SetBE16Bit(&rec_desc.first_block, NVM_INVALID_BLOCK_ID);
1665  memcpy((void *)data_ptr, (void *)&rec_desc, (size_t)sizeof(RECORD_DESCRIPTOR));
1666  data_ptr += (U16BIT)sizeof(RECORD_DESCRIPTOR);
1667 
1668  for (j = 0; j < database_access_lut[i].num_fields; j++)
1669  {
1670  if (database_access_lut[i].field[j].nvm_bit_size > 0)
1671  {
1672  // endian independent version of:
1673  // fld_desc.field_id = j;
1674  // fld_desc.field_offset = database_access_lut[i].field[j].nvm_bit_offset;
1675  STB_SetBE16Bit(&fld_desc.field_id, j);
1676  STB_SetBE16Bit(&fld_desc.field_offset, database_access_lut[i].field[j].nvm_bit_offset);
1677  fld_desc.field_size = database_access_lut[i].field[j].nvm_bit_size;
1678  fld_desc.padding[0] = 0;
1679  memcpy((void *)data_ptr, (void *)&fld_desc, (size_t)sizeof(FIELD_DESCRIPTOR));
1680  data_ptr += (U16BIT)sizeof(FIELD_DESCRIPTOR);
1681  }
1682  }
1683  }
1684  }
1685 
1686  FUNCTION_FINISH(WriteFormat);
1687 }
1688 
1689 static void BuildDatabase(U8BIT *data_ptr)
1690 {
1691  U8BIT rec_id, type;
1692  U16BIT offset, size, field_id;
1693  U16BIT i, nvm_blk;
1694  U32BIT value;
1695  void *rec_ptr;
1696  void *par_ptr;
1697  BOOLEAN reset_ram_access = FALSE;
1698 
1699  FUNCTION_START(BuildDatabase);
1700 
1701  if (data_ptr != STB_GetNVMAccessRAM())
1702  {
1703  // force NVM access to temp area
1704  STB_SetNVMAccessRAM(data_ptr);
1705  reset_ram_access = TRUE;
1706  }
1707 
1708  // build NVM map in RAM
1709  STB_InitNVMMap();
1710 
1711  // for every record type in the list
1712  for (rec_id = 0; rec_id < DBA_NUM_RECORDS; rec_id++)
1713  {
1714  // get first occurence of record in NVM and size of RAM record
1715  nvm_blk = GetStartNVMList(data_ptr, rec_id);
1716  while (nvm_blk != NVM_INVALID_BLOCK_ID)
1717  {
1718  // if NVM has a parent, get RAM parent record pointer
1719  if (GetNVMFieldParams(rec_id, DBA_FIELD_PARENT, &offset, &size))
1720  {
1721  value = STB_GetNVMRecordNumber(nvm_blk, offset, size);
1722  par_ptr = STB_FindRAMRecordFromNVMBlock((U16BIT)value);
1723  }
1724  else
1725  {
1726  par_ptr = NULL;
1727  }
1728 
1729  // create RAM record of same type
1730  rec_ptr = STB_CreateRAMRecord(rec_id, GetRAMRecSize(rec_id), nvm_blk, par_ptr);
1731  if (rec_ptr != NULL)
1732  {
1733  // copy any fields that exist in both NVM and RAM
1734  for (i = 0; i < database_access_lut[rec_id].num_fields; i++)
1735  {
1736  field_id = database_access_lut[rec_id].field[i].field_id;
1737  if (GetNVMFieldParams(rec_id, field_id, &offset, &size))
1738  {
1739  type = GetFieldType(field_id);
1740  switch (type)
1741  {
1742  case UNUM_TYPE:
1743  {
1744  value = STB_GetNVMRecordNumber(nvm_blk, offset, size);
1745  if ((value != 0) &&
1746  GetRAMFieldParams(rec_id, field_id, &offset, &size))
1747  {
1748  STB_SetRAMRecordNumber(rec_ptr, offset, size, value);
1749  }
1750  break;
1751  }
1752  case STR_TYPE:
1753  {
1754  U8BIT *str = STB_GetNVMRecordString(nvm_blk, offset, size);
1755  if ((str != NULL) &&
1756  GetRAMFieldParams(rec_id, field_id, &offset, &size))
1757  {
1758  STB_SetRAMRecordString(rec_ptr, offset, size, str);
1759  }
1760  break;
1761  }
1762  default:;
1763  }
1764  }
1765  }
1766  }
1767 
1768  // get next NVM record
1769  nvm_blk = STB_GetNextNVMBlock(nvm_blk);
1770  }
1771  }
1772 
1773  if (reset_ram_access)
1774  {
1775  // restore NVM access to device
1776  STB_SetNVMAccessRAM(NULL);
1777  }
1778 
1779  FUNCTION_FINISH(BuildDatabase);
1780 }
1781 
1782 static void ConvertDatabase(U8BIT *data_ptr)
1783 {
1784  U8BIT i, j;
1785  DATABASE_DESCRIPTOR *db_ptr;
1786  RECORD_DESCRIPTOR *rd_ptr;
1787  FIELD_DESCRIPTOR *fd_ptr;
1788  DATABASE_DESCRIPTOR db_desc;
1789  RECORD_DESCRIPTOR *rec_desc;
1790  FIELD_DESCRIPTOR **fld_desc;
1791 
1792  FUNCTION_START(ConvertDatabase);
1793 
1794  // parse database descriptors
1795  db_ptr = (DATABASE_DESCRIPTOR *)(data_ptr + (U32BIT)sizeof(DATABASE_FORMAT));
1796  // endian independent version of:
1797  // db_desc.desc_size = db_ptr->desc_size;
1798  db_desc.desc_size = STB_GetBE16Bit(&db_ptr->desc_size);
1799  db_desc.num_records = db_ptr->num_records;
1800  db_ptr++;
1801 
1802  rec_desc = (RECORD_DESCRIPTOR *)STB_GetMemory((U32BIT)(sizeof(RECORD_DESCRIPTOR) * db_desc.num_records));
1803  fld_desc = (FIELD_DESCRIPTOR **)STB_GetMemory((U32BIT)(sizeof(RECORD_DESCRIPTOR *) * db_desc.num_records));
1804  if ((rec_desc != NULL) && (fld_desc != NULL))
1805  {
1806  rd_ptr = (RECORD_DESCRIPTOR *)db_ptr;
1807  for (i = 0; i < db_desc.num_records; i++)
1808  {
1809  rec_desc[i].record_id = rd_ptr->record_id;
1810  rec_desc[i].num_fields = rd_ptr->num_fields;
1811  rd_ptr++;
1812 
1813  fd_ptr = (FIELD_DESCRIPTOR *)rd_ptr;
1814  fld_desc[i] = (FIELD_DESCRIPTOR *)STB_GetMemory((U32BIT)(sizeof(FIELD_DESCRIPTOR) * rec_desc[i].num_fields));
1815  if (fld_desc[i] != NULL)
1816  {
1817  for (j = 0; j < rec_desc[i].num_fields; j++)
1818  {
1819  // endian independent version of:
1820  // fld_desc[i][j].field_id = fd_ptr->field_id;
1821  // fld_desc[i][j].field_offset = fd_ptr->field_offset;
1822  fld_desc[i][j].field_id = STB_GetBE16Bit(&fd_ptr->field_id);
1823  fld_desc[i][j].field_offset = STB_GetBE16Bit(&fd_ptr->field_offset);
1824  fld_desc[i][j].field_size = fd_ptr->field_size;
1825  fd_ptr++;
1826  }
1827  }
1828  rd_ptr = (RECORD_DESCRIPTOR *)fd_ptr;
1829  }
1830  }
1831 
1832  // delete memory used
1833  if (fld_desc != NULL)
1834  {
1835  for (i = 0; i < db_desc.num_records; i++)
1836  {
1837  STB_FreeMemory((void *)fld_desc[i]);
1838  }
1839  STB_FreeMemory((void *)fld_desc);
1840  }
1841  STB_FreeMemory((void *)rec_desc);
1842 
1843  FUNCTION_FINISH(ConvertDatabase);
1844 }
1845 
1846 static void ClearDatabase(void)
1847 {
1848  U8BIT rec_id, i;
1849  U16BIT field_id, field_offset, field_size;
1850  void *field_val;
1851  void *rec_ptr;
1852 
1853  FUNCTION_START(ClearDatabase);
1854 
1855  /* For every record type in the list */
1856  for (rec_id = 0; rec_id < DBA_NUM_RECORDS; rec_id++)
1857  {
1858  for (i = 0; i < database_access_lut[rec_id].num_fields; i++)
1859  {
1860  field_id = database_access_lut[rec_id].field[i].field_id;
1861  if (GetFieldType(field_id) == PTR_TYPE)
1862  {
1863  if (GetRAMFieldParams(rec_id, field_id, &field_offset, &field_size))
1864  {
1865  ASSERT(field_size == sizeof(void*));
1866  /* Free memory used by any pointer fields */
1867  rec_ptr = STB_FindRAMRecordFromId(rec_id, NULL, NULL);
1868  while (rec_ptr != NULL)
1869  {
1870  field_val = STB_GetRAMRecordPointer(rec_ptr, field_offset);
1871  STB_FreeMemory(field_val);
1872  rec_ptr = STB_FindRAMRecordFromId(rec_id, NULL, rec_ptr);
1873  }
1874  }
1875  }
1876  }
1877  }
1878 
1879  /* Delete any existing RAM records */
1881 
1882  FUNCTION_FINISH(ClearDatabase);
1883 }
1884 
1885 static U8BIT GetFieldType(U16BIT field_id)
1886 {
1887  U16BIT i;
1888  U16BIT num_fields = sizeof(database_field_type) / sizeof(database_field_type[0]);
1889  U8BIT ret_val = 0;
1890 
1891  FUNCTION_START(GetFieldType);
1892 
1893  // find field id in type LUT
1894  for (i = 0; i < num_fields; i++)
1895  {
1896  if (database_field_type[i].field_id == field_id)
1897  {
1898  ret_val = (U8BIT)database_field_type[i].type;
1899  break;
1900  }
1901  }
1902 
1903  FUNCTION_FINISH(GetFieldType);
1904 
1905  return(ret_val);
1906 }
1907 
1908 static U16BIT GetNVMRecSize(U8BIT rec_id)
1909 {
1910  U16BIT rec_size, max_size;
1911  U8BIT i;
1912 
1913  FUNCTION_START(GetNVMRecSize);
1914 
1915  /* Get maximum number of bits used for a field (offset + size) */
1916  max_size = 0;
1917  for (i = 0; i < database_access_lut[rec_id].num_fields; i++)
1918  {
1919  rec_size = database_access_lut[rec_id].field[i].nvm_bit_offset;
1920  rec_size += (U16BIT)database_access_lut[rec_id].field[i].nvm_bit_size;
1921  if (rec_size > max_size)
1922  {
1923  max_size = rec_size;
1924  }
1925  }
1926 
1927  /* Round up to number of complete bytes */
1928  if ((max_size % 8) > 0)
1929  {
1930  max_size += (8 - (max_size % 8));
1931  }
1932 
1933  /* Convert to bytes */
1934  max_size = (max_size >> 3);
1935 
1936  FUNCTION_FINISH(GetNVMRecSize);
1937 
1938  return(max_size);
1939 }
1940 
1941 static U16BIT GetRAMRecSize(U8BIT rec_id)
1942 {
1943  U16BIT rec_size, max_size;
1944  U8BIT i;
1945 
1946  FUNCTION_START(GetRAMRecSize);
1947 
1948  /* Get maximum number of bytes used for a field (offset + size) */
1949  max_size = 0;
1950  for (i = 0; i < database_access_lut[rec_id].num_fields; i++)
1951  {
1952  rec_size = database_access_lut[rec_id].field[i].ram_byte_offset;
1953  rec_size += (U16BIT)database_access_lut[rec_id].field[i].ram_byte_size;
1954  if (rec_size > max_size)
1955  {
1956  max_size = rec_size;
1957  }
1958  }
1959 
1960  FUNCTION_FINISH(GetRAMRecSize);
1961 
1962  return(max_size);
1963 }
1964 
1965 static BOOLEAN GetNVMFieldParams(U8BIT rec_id, U16BIT field_id, U16BIT *offset, U16BIT *size)
1966 {
1967  U8BIT i;
1968  BOOLEAN ret_val = FALSE;
1969 
1970  FUNCTION_START(GetNVMFieldParams);
1971 
1972  ASSERT(rec_id < DBA_NUM_RECORDS);
1973  ASSERT(offset != NULL);
1974  ASSERT(size != NULL);
1975 
1976  for (i = 0; i < database_access_lut[rec_id].num_fields; i++)
1977  {
1978  if (database_access_lut[rec_id].field[i].field_id == field_id)
1979  {
1980  *offset = database_access_lut[rec_id].field[i].nvm_bit_offset;
1981  *size = database_access_lut[rec_id].field[i].nvm_bit_size;
1982  if (*size > 0)
1983  {
1984  ret_val = TRUE;
1985  }
1986  break;
1987  }
1988  }
1989 
1990  FUNCTION_FINISH(GetNVMFieldParams);
1991 
1992  return(ret_val);
1993 }
1994 
1995 static BOOLEAN GetRAMFieldParams(U8BIT rec_id, U16BIT field_id, U16BIT *offset, U16BIT *size)
1996 {
1997  U8BIT i;
1998  BOOLEAN ret_val = FALSE;
1999 
2000  FUNCTION_START(GetRAMFieldParams);
2001 
2002  ASSERT(rec_id < DBA_NUM_RECORDS);
2003  ASSERT(offset != NULL);
2004  ASSERT(size != NULL);
2005 
2006  for (i = 0; i < database_access_lut[rec_id].num_fields; i++)
2007  {
2008  if (database_access_lut[rec_id].field[i].field_id == field_id)
2009  {
2010  *offset = database_access_lut[rec_id].field[i].ram_byte_offset;
2011  *size = database_access_lut[rec_id].field[i].ram_byte_size;
2012  if (*size > 0)
2013  {
2014  ret_val = TRUE;
2015  }
2016  break;
2017  }
2018  }
2019 
2020  FUNCTION_FINISH(GetRAMFieldParams);
2021 
2022  return(ret_val);
2023 }
2024 
2025 static void AddToNVMList(void *rec_ptr)
2026 {
2027  U8BIT rec_id;
2028  U16BIT nvm_block;
2029 
2030  FUNCTION_START(AddToNVMList);
2031 
2032  ASSERT(rec_ptr != NULL);
2033 
2034  rec_id = STB_GetRAMRecordId(rec_ptr);
2035  nvm_block = STB_GetRAMRecordNVMBlock(rec_ptr);
2036  if (STB_GetRAMRecordPrevNVMBlock(rec_ptr) == NVM_INVALID_BLOCK_ID)
2037  {
2038  SetStartNVMList(rec_id, nvm_block);
2040  }
2041  else
2042  {
2045  }
2046 
2047  FUNCTION_FINISH(AddToNVMList);
2048 }
2049 
2050 static void SetStartNVMList(U8BIT rec_id, U16BIT block_no)
2051 {
2052  U8BIT i;
2053  U16BIT offset;
2054  DATABASE_DESCRIPTOR db_desc;
2055  RECORD_DESCRIPTOR rec_desc;
2056 
2057  FUNCTION_START(SetStartNVMList);
2058 
2059  ASSERT(rec_id < DBA_NUM_RECORDS);
2060 
2061  offset = (U16BIT)sizeof(DATABASE_FORMAT);
2062  if (STB_ReadNVMData(offset, sizeof(DATABASE_DESCRIPTOR), (U8BIT *)&db_desc))
2063  {
2064  offset += (U16BIT)sizeof(DATABASE_DESCRIPTOR);
2065  for (i = 0; i < db_desc.num_records; i++)
2066  {
2067  if (STB_ReadNVMData(offset, sizeof(RECORD_DESCRIPTOR), (U8BIT *)&rec_desc))
2068  {
2069  if (rec_desc.record_id == rec_id)
2070  {
2071  // endian independent version of:
2072  // rec_desc.first_block = block_no;
2073  STB_SetBE16Bit(&rec_desc.first_block, block_no);
2074  STB_WriteNVMData(offset, sizeof(RECORD_DESCRIPTOR), (U8BIT *)&rec_desc);
2075  break;
2076  }
2077  offset += (U16BIT)sizeof(RECORD_DESCRIPTOR);
2078  offset += (U16BIT)(sizeof(FIELD_DESCRIPTOR) * rec_desc.num_fields);
2079  }
2080  }
2081  }
2082 
2083  FUNCTION_FINISH(SetStartNVMList);
2084 }
2085 
2086 static U16BIT GetStartNVMList(U8BIT *data_ptr, U8BIT rec_id)
2087 {
2088  U8BIT i;
2089  U16BIT offset;
2090  DATABASE_DESCRIPTOR db_desc;
2091  RECORD_DESCRIPTOR rec_desc;
2092  U16BIT ret_val = NVM_INVALID_BLOCK_ID;
2093 
2094  FUNCTION_START(GetStartNVMList);
2095 
2096  ASSERT(rec_id < DBA_NUM_RECORDS);
2097 
2098  if (data_ptr == NULL)
2099  {
2100  // read fron NVM
2101  offset = (U16BIT)sizeof(DATABASE_FORMAT);
2102  if (STB_ReadNVMData(offset, sizeof(DATABASE_DESCRIPTOR), (U8BIT *)&db_desc))
2103  {
2104  offset += (U16BIT)sizeof(DATABASE_DESCRIPTOR);
2105  for (i = 0; i < db_desc.num_records; i++)
2106  {
2107  if (STB_ReadNVMData(offset, sizeof(RECORD_DESCRIPTOR), (U8BIT *)&rec_desc))
2108  {
2109  if (rec_desc.record_id == rec_id)
2110  {
2111  // endian independent version of:
2112  // ret_val = rec_desc.first_block;
2113  ret_val = STB_GetBE16Bit(&rec_desc.first_block);
2114  break;
2115  }
2116  offset += (U16BIT)sizeof(RECORD_DESCRIPTOR);
2117  offset += (U16BIT)(sizeof(FIELD_DESCRIPTOR) * rec_desc.num_fields);
2118  }
2119  }
2120  }
2121  }
2122  else
2123  {
2124  // read fron RAM buffer
2125  data_ptr += (U16BIT)sizeof(DATABASE_FORMAT);
2126  memcpy((void *)&db_desc, (void *)data_ptr, (size_t)sizeof(DATABASE_DESCRIPTOR));
2127  data_ptr += (U16BIT)sizeof(DATABASE_DESCRIPTOR);
2128  for (i = 0; i < db_desc.num_records; i++)
2129  {
2130  memcpy((void *)&rec_desc, (void *)data_ptr, (size_t)sizeof(RECORD_DESCRIPTOR));
2131  if (rec_desc.record_id == rec_id)
2132  {
2133  // endian independent version of:
2134  // ret_val = rec_desc.first_block;
2135  ret_val = STB_GetBE16Bit(&rec_desc.first_block);
2136  break;
2137  }
2138  data_ptr += (U16BIT)sizeof(RECORD_DESCRIPTOR);
2139  data_ptr += (U16BIT)(sizeof(FIELD_DESCRIPTOR) * rec_desc.num_fields);
2140  }
2141  }
2142 
2143  FUNCTION_FINISH(GetStartNVMList);
2144 
2145  return(ret_val);
2146 }
2147 
2148 static void RemoveFromNVMList(void *rec_ptr)
2149 {
2150  U8BIT rec_id;
2151 
2152  FUNCTION_START(RemoveFromNVMList);
2153 
2154  ASSERT(rec_ptr != NULL);
2155 
2156  rec_id = STB_GetRAMRecordId(rec_ptr);
2157  if (STB_GetRAMRecordPrevNVMBlock(rec_ptr) == NVM_INVALID_BLOCK_ID)
2158  {
2159  SetStartNVMList(rec_id, STB_GetRAMRecordNextNVMBlock(rec_ptr));
2160  }
2161  else
2162  {
2164  }
2165 
2166  FUNCTION_FINISH(RemoveFromNVMList);
2167 }
2168 
2169 static void DestroyRecord(void *rec_ptr)
2170 {
2171  U8BIT rec_id, i;
2172  U16BIT nvm_block, field_id, field_offset, field_size;
2173  void *field_val;
2174 
2175  FUNCTION_START(DestroyRecord);
2176 
2177  ASSERT(rec_ptr != NULL);
2178 
2179  /* Free memory used by any pointer fields */
2180  rec_id = STB_GetRAMRecordId(rec_ptr);
2181  for (i = 0; i < database_access_lut[rec_id].num_fields; i++)
2182  {
2183  field_id = database_access_lut[rec_id].field[i].field_id;
2184  if (GetFieldType(field_id) == PTR_TYPE)
2185  {
2186  if (GetRAMFieldParams(rec_id, field_id, &field_offset, &field_size))
2187  {
2188  ASSERT(field_size == sizeof(void*));
2189  field_val = STB_GetRAMRecordPointer(rec_ptr, field_offset);
2190 
2191  if (field_val != NULL)
2192  {
2193  STB_FreeMemory(field_val);
2194  }
2195  }
2196  }
2197  }
2198 
2199  // if it has a NVM record
2200  nvm_block = STB_GetRAMRecordNVMBlock(rec_ptr);
2201  if (nvm_block != NVM_INVALID_BLOCK_ID)
2202  {
2203  // repair linked list
2204  RemoveFromNVMList(rec_ptr);
2205 
2206  // destroy NVM record
2207  STB_DestroyNVMRecord(nvm_block);
2208  }
2209 
2210  // destroy RAM record
2211  STB_DestroyRAMRecord(rec_ptr);
2212 
2213  FUNCTION_FINISH(DestroyRecord);
2214 }
2215 
U32BIT STB_GetNVMRecordNumber(U16BIT block_no, U16BIT offset, U16BIT size)
Reads the specified value of a field from a NVM record.
Definition: stbdbnvm.c:1208
U16BIT STB_GetNextNVMBlock(U16BIT block_no)
Returns the block number of the next NVM record pointed to by the NVM record starting at the specifie...
Definition: stbdbnvm.c:918
U16BIT STB_GetRAMRecordNVMBlock(void *rec_ptr)
Returns NVM block number for given record pointer.
Definition: stbdbram.c:249
BOOLEAN DBA_ImportFromXML(U8BIT *xml_pathname)
Imports records from the given XML file into the working database. If a record already exists in the ...
Definition: dba_nvm.c:855
void * DBA_CreateRecord(U32BIT record_id, void *parent)
Creates a new record of the given type, adding it to the database as a child of the given parent reco...
Definition: dba_nvm.c:940
void * STB_GetMemory(U32BIT bytes)
Attempts to allocate memory from the heap.
Definition: stbheap.c:221
void STB_DestroyNVMRecord(U16BIT block_no)
Destroys NVM record by marking all NVM blocks used by the record as invalid.
Definition: stbdbnvm.c:805
NVM database access defines, structures and functions.
void STB_NVMInitialise(void)
Initialises NVM control.
Definition: stbnvm.c:284
BOOLEAN STB_CheckNVMDatabaseIntegrity(void)
Reads each database block from NVM and checks its checksum. If the data has already been read into th...
Definition: stbdbnvm.c:564
BOOLEAN DBA_SaveDatabase(void)
Saves any changes made to the working database to non-volatile storage. If saving to a file...
Definition: dba_nvm.c:667
BOOLEAN STB_NVMSTBRead(U32BIT offset, U32BIT bytes, U8BIT *dest_addr)
Reads bytes from the given position of the STB area of NVM.
Definition: stbnvm.c:506
BOOLEAN DBA_RestoreDatabase(void)
Restores the working database from a previously made backup copy.
Definition: dba_nvm.c:789
Header file - Function prototypes for RAM database.
BOOLEAN DBA_BackupDatabase(U8BIT *pathname)
Creates a backup copy of the working database. Whether the backup database is saved to non-volatile s...
Definition: dba_nvm.c:723
void * STB_GetRAMRecordParent(void *rec_ptr)
Returns parent pointer for given record pointer.
Definition: stbdbram.c:343
void * STB_OSCreateSemaphore(void)
Create a Semaphore.
U8BIT * STB_GetNVMRecordString(U16BIT block_no, U16BIT offset, U16BIT size)
Reads string of a field from a NVM record.
Definition: stbdbnvm.c:1171
void STB_SetNVMRecordString(U16BIT block_no, U16BIT offset, U16BIT size, U8BIT *string)
Writes the specified value into a field of a NVM record.
Definition: stbdbnvm.c:1074
void STB_NVMSave(void)
Saves the RAM cache data to NVM.
Definition: stbdbnvm.c:1047
void * STB_GetRAMRecordPointer(void *rec_ptr, U16BIT offset)
Reads the specified value of a field from a RAM record.
Definition: stbdbram.c:737
BOOLEAN DBA_SetFieldLangString(void *record, U32BIT field_id, U32BIT lang_code, U8BIT *string, U16BIT num_bytes)
Set the string value of a record&#39;s field. The function will fail if the record doesn&#39;t exist...
Definition: dba_nvm.c:1291
void STB_SetRAMRecordString(void *rec_ptr, U16BIT offset, U16BIT size, U8BIT *string)
Writes the specified string into a field of a RAM record.
Definition: stbdbram.c:552
U32BIT DBA_DataBlockSize(U32BIT data_block_id)
Returns the number of bytes available for the given data block.
Definition: dba_nvm.c:1508
void DBA_SaveRecord(void *record)
Forces a record to be saved to non-volatile storage. Depending on the implementation, this function may not do anything if the data is updated to non-volatile storage as any records and/or fields are created or updated.
Definition: dba_nvm.c:1157
void DBA_EraseBackupDatabase(void)
Erases the backup copy of the database. If data was stored in non-volatile storage then this should b...
Definition: dba_nvm.c:822
void STB_SetBE16Bit(U16BIT *addr, U16BIT value)
Stores 16bit int in address, forcing value to be stored in Big endian format.
Definition: stbcsum.c:167
BOOLEAN DBA_GetFieldData(void *record, U32BIT field_id, U8BIT **data, U16BIT *num_bytes)
Gets the data of a record&#39;s field. The function will fail if the record doesn&#39;t exist, the record doesn&#39;t include the given field, or the field isn&#39;t a data field. The pointer to the data returned will be to the data held by the database, so the data must not be changed.
Definition: dba_nvm.c:1488
void STB_InitNVMAccess(U16BIT offset)
Initialises parameters needed for NVM block access.
Definition: stbdbnvm.c:472
Header file - Function prototypes for NVM control.
U32BIT DBA_DatabaseFileSize(U32BIT *max_size)
Returns the size in bytes of the database as stored in non-volatile storage.
Definition: dba_nvm.c:915
void STB_OSSemaphoreSignal(void *semaphore)
Signal a Semaphore to Release it by decrementing its counter.
BOOLEAN DBA_LoadDatabase(U8BIT *pathname)
Reads a database from non-volatile storage, creating any structures in memory that will be required t...
Definition: dba_nvm.c:541
BOOLEAN DBA_DataBlockWrite(U32BIT data_block_id, U8BIT *data, U32BIT num_bytes)
Writes a block of data into the database from the given buffer.
Definition: dba_nvm.c:1560
void * STB_CreateRAMRecord(U8BIT rec_id, U16BIT size, U16BIT nvm_block, void *parent)
Creates a record of the type given in RAM (mallocs block).
Definition: stbdbram.c:156
void STB_OSDeleteSemaphore(void *semaphore)
Delete a Semaphore.
BOOLEAN DBA_GetFieldLangString(void *record, U32BIT field_id, U32BIT lang_code, U8BIT **string, U16BIT *num_bytes)
Gets the string value of a record&#39;s field. The function will fail if the record doesn&#39;t exist...
Definition: dba_nvm.c:1460
void STB_SetNVMRecordNumber(U16BIT block_no, U16BIT offset, U16BIT size, U32BIT value)
Writes the specified value into a field of a NVM record.
Definition: stbdbnvm.c:1120
Header file - Function prototypes for NVM database.
void STB_OSSemaphoreWait(void *semaphore)
Wait on Semaphore Indefinity or Until Released.
void STB_SetRAMRecordParent(void *rec_ptr, void *parent)
Sets parent pointer for given record pointer.
Definition: stbdbram.c:370
U8BIT STB_CalcChecksum(U8BIT *data_ptr, U32BIT data_size)
Calculates the checksum to zero for the data block provided.
Definition: stbcsum.c:62
U32BIT STB_GetRAMRecordNumber(void *rec_ptr, U16BIT offset, U16BIT size)
Reads the specified value of a field from a RAM record.
Definition: stbdbram.c:697
BOOLEAN DBA_ExportToXML(U8BIT *xml_pathname)
Export the working database to an XML file.
Definition: dba_nvm.c:840
void STB_SetNextNVMBlock(U16BIT block_no, U16BIT next_block)
Repairs NVM linked list by pointing the NVM record starting at the specified block number to the reco...
Definition: stbdbnvm.c:865
void STB_FreeMemory(void *addr)
Releases previously allocated heap memory.
Definition: stbheap.c:336
U8BIT * STB_GetRAMRecordString(void *rec_ptr, U16BIT offset, U16BIT size)
Reads the specified value of a field from a RAM record.
Definition: stbdbram.c:667
U8BIT * DBA_DatabaseVersion(void)
Returns a version string representing the working database.
Definition: dba_nvm.c:887
BOOLEAN DBA_GetFieldString(void *record, U32BIT field_id, U8BIT **string, U16BIT *num_bytes)
Gets the string value of a record&#39;s field. The function will fail if the record doesn&#39;t exist...
Definition: dba_nvm.c:1400
void STB_InitRAMAccess(void)
Initialises parameters needed for RAM record access.
Definition: stbdbram.c:79
U16BIT STB_GetRAMRecordNextNVMBlock(void *rec_ptr)
Returns NVM block number for next record of given pointer.
Definition: stbdbram.c:309
BOOLEAN STB_NVMDataBlockRead(U32BIT data_block_id, U32BIT num_bytes, U8BIT *dest_addr)
Reads data bytes for the given data block from NVM.
Definition: stbnvm.c:332
U32BIT STB_NVMGetDataBlockSize(U32BIT data_block_id)
Returns the number of bytes of data stored for the given data block.
Definition: stbnvm.c:302
U16BIT STB_GetBE16Bit(U16BIT *addr)
Returns 16bit int from address, assuming value is stored in Big endian format.
Definition: stbcsum.c:138
BOOLEAN DBA_Initialise(void)
Performs any initialisation required prior to the database being loaded.
Definition: dba_nvm.c:482
BOOLEAN DBA_SetFieldString(void *record, U32BIT field_id, U8BIT *string, U16BIT num_bytes)
Set the string value of a record&#39;s field. The function will fail if the record doesn&#39;t exist...
Definition: dba_nvm.c:1227
Debug functions header file.
void * STB_FindRAMRecordFromId(U8BIT rec_id, void *parent, void *last_rec)
Returns pointer to RAM structure for the given record type. Finds the next record in the list after t...
Definition: stbdbram.c:445
Database access defines, structures and public functions.
void * DBA_FindRecord(U32BIT record_id, void *parent, void *last_rec)
Finds the next record, of the given type, that comes after last_rec. last_rec must be the same type o...
Definition: dba_nvm.c:1055
U16BIT STB_CreateNVMRecord(U8BIT rec_id, U16BIT size)
Creates a record of the type given in NVM by overwriting invalid blocks.
Definition: stbdbnvm.c:731
void STB_PurgeRAMRecords(void)
Initialises RAM database by destroying all records and linked lists.
Definition: stbdbram.c:111
void STB_SetRAMRecordNumber(void *rec_ptr, U16BIT offset, U16BIT size, U32BIT value)
Writes the specified value into a field of a RAM record.
Definition: stbdbram.c:593
BOOLEAN DBA_CanRestoreDatabase(void)
Checks whether the working database can be restored from a backup copy.
Definition: dba_nvm.c:766
Header for STB unicode string handling routines.
U8BIT STB_GetRAMRecordId(void *rec_ptr)
Returns record type id for given record pointer.
Definition: stbdbram.c:223
void STB_WriteNVMData(U16BIT offset, U16BIT size, U8BIT *data_ptr)
Writes the given data to NVM.
Definition: stbdbnvm.c:1262
U32BIT STB_GetNumBytesInString(U8BIT *string_ptr)
Determines the no of bytes of the given string.
Definition: stbuni.c:311
U32BIT DBA_DataBlockRead(U32BIT data_block_id, U8BIT *data, U32BIT num_bytes)
Read a block of data from the database into the given buffer.
Definition: dba_nvm.c:1528
void STB_InitNVMMap(void)
Initialises parameters needed for NVM block access (calcs num blocks if required) ...
Definition: stbdbnvm.c:504
U16BIT STB_GetNVMBlocksUsed(void)
Returns total number of NVM database blocks in use.
Definition: stbdbnvm.c:661
BOOLEAN STB_ReadNVMData(U16BIT offset, U16BIT size, U8BIT *data_ptr)
Reads data from the NVM into the given buffer.
Definition: stbdbnvm.c:1297
Header file - Function prototypes for operating system.
System Wide Global Technical Data Type Definitions.
BOOLEAN DBA_SetFieldValue(void *record, U32BIT field_id, U32BIT value)
Set the value of a record&#39;s field. The function will fail if the record doesn&#39;t exist, the record doesn&#39;t include the given field, or the field is a string value.
Definition: dba_nvm.c:1175
U16BIT STB_GetNVMBlockCount(void)
Returns total number of NVM database blocks.
Definition: stbdbnvm.c:637
BOOLEAN STB_CheckChecksum(U8BIT *data_ptr, U32BIT data_size)
Validates the checksum to zero for the block pointer provided.
Definition: stbcsum.c:96
Header file - Function prototypes for check sum calcs.
BOOLEAN DBA_SetFieldData(void *record, U32BIT field_id, U8BIT *data, U16BIT num_bytes)
Set a variable amount of data of a record&#39;s field. The function will fail if the record doesn&#39;t exist...
Definition: dba_nvm.c:1318
U16BIT STB_GetRAMRecordPrevNVMBlock(void *rec_ptr)
Returns NVM block number for previous record of given pointer.
Definition: stbdbram.c:275
BOOLEAN STB_NVMSTBWrite(U32BIT offset, U32BIT bytes, U8BIT *src_addr)
Writes bytes into the given position of the STB area of NVM.
Definition: stbnvm.c:539
Header file - Function prototypes for heap memory.
void DBA_DestroyRecord(void *record)
Destroys the given record, removing it from the database and freeing any memory associated with it...
Definition: dba_nvm.c:1013
BOOLEAN DBA_ClearDatabase(void)
Clears the working database of all records. Following this call, it should still be possible to acces...
Definition: dba_nvm.c:694
void STB_SetNVMAccessRAM(U8BIT *ram_ptr)
Sets all DB NVM access to RAM block supplied instead of NVM (cancel if NULL).
Definition: stbdbnvm.c:599
BOOLEAN STB_NVMDataBlockWrite(U32BIT data_block_id, U32BIT num_bytes, U8BIT *src_addr)
Writes data bytes for the given data block to NVM.
Definition: stbnvm.c:363
void DBA_LockDatabase(void)
Locks the database to prevent access from other threads or processes.
Definition: dba_nvm.c:866
U32BIT STB_NVMGetSTBSize(void)
Returns size of STB database storage are (in bytes).
Definition: stbnvm.c:478
void DBA_UnlockDatabase(void)
Unlocks the database to allow other threads or processes to access it.
Definition: dba_nvm.c:876
BOOLEAN DBA_GetFieldValue(void *record, U32BIT field_id, U32BIT *value)
Gets the value of a record&#39;s field. The function will fail if the record doesn&#39;t exist, the record doesn&#39;t include the given field, or the field is a string value.
Definition: dba_nvm.c:1341
void DBA_Terminate(void)
Releases any resources acquired by initialisation and clears any currently loaded database...
Definition: dba_nvm.c:508
void STB_DestroyRAMRecord(void *rec_ptr)
Destroys record given in RAM (frees block).
Definition: stbdbram.c:197
void STB_NVMFlushCache(BOOLEAN clear)
Flush cached changes.
Definition: stbdbnvm.c:1017
void DBA_SetRecordParent(void *record, void *parent)
Set of change the parent of the given record.
Definition: dba_nvm.c:1080
void * STB_FindRAMRecordFromNVMBlock(U16BIT nvm_block)
Returns pointer to RAM structure which relates to the given NVM record block no.
Definition: stbdbram.c:510
U16BIT STB_GetNVMBlockSize(void)
Returns the size of an NVM database block, in bytes.
Definition: stbdbnvm.c:686
U8BIT * STB_GetNVMAccessRAM(void)
Returns the current RAM pointer used for DB NVM access.
Definition: stbdbnvm.c:619
void * DBA_GetRecordParent(void *record)
Returns the handle to the parent of the given record.
Definition: dba_nvm.c:1129