comparison src/ui/mfw/mfw_utils.c @ 3:67bfe9f274f6

src/ui: import of src/ui3 from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:33:10 +0000
parents
children 92abb46dc1ba
comparison
equal deleted inserted replaced
2:3a14ee9a9843 3:67bfe9f274f6
1 /*
2 +--------------------------------------------------------------------+
3 | PROJECT: MMI-Framework (8417) $Workfile:: mfw_utils.c $|
4 | $Author:: NDH $Revision:: 1 $|
5 | CREATED: 6.1.2003 $Modtime:: 10.04.00 14:58 $|
6 | STATE : code $|
7 +--------------------------------------------------------------------+
8
9 MODULE : MFW_UTILS
10
11 PURPOSE : This modul contains General Functional Utilities.
12
13 HISTORY:
14 Oct 04, 2004 REF: CRR 25519 Deepa M.D
15 Bug:Re-align structure members in MFW
16 Fix:Structure elements have been realigned to avoid the structure padding
17
18 Jun 05, 2004 REF: CRR 18262 NISHIKANT KULKARNI
19 Description: The sample sends a STOP DTMF message without release of the key by the user
20 Solution: Instead of sending DTMF commands in "VTS_MOD_Auto" mode, on key press DTMF tone is started
21 using VTS_MOD_ManStart and on key release DTMF tone is stopped using VTS_MOD_ManStop mode.
22
23 */
24
25 #include <string.h>
26
27
28 #if defined (NEW_FRAME)
29
30 #include "typedefs.h"
31 #include "vsi.h"
32 #include "pei.h"
33 #include "custom.h"
34 #include "gsm.h"
35
36 #else
37
38 #include "STDDEFS.H"
39 #include "custom.h"
40 #include "gsm.h"
41 #include "vsi.h"
42
43 #endif
44
45 #include "mfw_mfw.h"
46 #include "mfw_utils.h"
47
48 #include "cus_aci.h"
49 #include "prim.h"
50 #ifndef PCM_2_FFS
51 #include "pcm.h"
52 #endif
53
54
55 // xnkulkar SPR-18262: This length of array for storing DTMF mode (Start/Stop), is equal to the number
56 // of DTMF tone requests that can be stored in queue.
57 #define MAX_DTMF_Q_ENTRIES 50
58 /***************************Go-lite Optimization changes start***********************/
59 //Oct 04, 2004 REF: CRR 25519 Deepa M.D
60 //Structure elements (T_MFW_CBUF_HEADER)are realigned to avoid the structure padding
61 typedef struct
62 { //xnkulkar SPR-18262: This member is used to store the mode for various DTMF tones present in queue to be sent.
63 UBYTE vts_mode[MAX_DTMF_Q_ENTRIES];
64 USHORT item_size;
65 UBYTE *mfw_cb;
66 ULONG mfw_cb_read_pos;
67 ULONG mfw_cb_write_pos;
68 USHORT num_elements;
69 USHORT max_num_items;
70 UBYTE null_char;
71 UBYTE overwrite;
72 UBYTE static_buf;
73 UBYTE active;
74 } T_MFW_CBUF_HEADER;
75 /***************************Go-lite Optimization changes end***********************/
76
77 static T_MFW_CBUF_HEADER cbf_hdr[MAX_CBUF_QUEUES];
78 static UBYTE cbf_num_of_buffers;
79
80
81 /*
82 ** Static Function Prototypes
83 */
84 static SHORT mfw_cbuf_get_free_id(void);
85
86 /*
87 +--------------------------------------------------------------------+
88 | PROJECT: MMI-Framework (8417) MODULE: MFW_CBUF |
89 | STATE : code ROUTINE: (static) mfw_cbuf_init |
90 +--------------------------------------------------------------------+
91
92
93 PURPOSE : Create and Initialise the Circular Buffer
94
95 */
96 SHORT mfw_cbuf_create (USHORT max_num_items, USHORT item_size,
97 UBYTE overwrite, UBYTE null_char,
98 UBYTE static_buf, void *buffer_ptr)
99 {
100 SHORT bufId;
101
102 if (cbf_num_of_buffers < MAX_CBUF_QUEUES)
103 {
104 /*
105 ** Get the first available Id for a free buffer
106 */
107 bufId = mfw_cbuf_get_free_id();
108 if (bufId == MFW_CBUF_NO_BUFS_AVAILABLE)
109 return (MFW_CBUF_NO_BUFS_AVAILABLE);
110 }
111 else
112 {
113 /*
114 ** return -1 as an indication that there are no more buffer handles available
115 */
116 return (MFW_CBUF_NO_BUFS_AVAILABLE);
117 }
118
119 /*
120 ** We now have a valid bufferId but check the validity of the incoming parameters
121 ** before we allocate the buffer.
122 */
123 if (item_size == 0)
124 return (MFW_CBUF_INVALID_ITEM_SIZE);
125
126 if (max_num_items == 0)
127 return (MFW_CBUF_INVALID_MAX_ITEMS);
128
129 if ((static_buf) && (buffer_ptr == (void *)0))
130 return (MFW_CBUF_INVALID_BUF_PTR);
131
132 if ((!static_buf) && (buffer_ptr != (void *)0))
133 return (MFW_CBUF_INVALID_BUF_PTR);
134
135 /*
136 ** Set the selected buffer to active
137 */
138 cbf_hdr[bufId].active = TRUE;
139
140 if (!static_buf)
141 {
142 /*
143 ** If the buffer isn't static, then get the dynamic memory for it.
144 */
145 cbf_hdr[bufId].mfw_cb = mfwAlloc(item_size * max_num_items);
146 cbf_hdr[bufId].static_buf = FALSE;
147
148 if (cbf_hdr[bufId].mfw_cb == (void *)0)
149 {
150 /*
151 ** The memory Allocation failed, mark the buffer as inactive and return an error
152 */
153 cbf_hdr[bufId].active = FALSE;
154 return (MFW_CBUF_MEM_ALLOC_FAILURE);
155 }
156 }
157 else
158 {
159 /*
160 ** If the buffer is static, the calling function will have provided a
161 ** pointer to the buffer to be used.
162 */
163 cbf_hdr[bufId].mfw_cb = (UBYTE *)buffer_ptr;
164 cbf_hdr[bufId].static_buf = TRUE;
165 }
166
167 /*
168 ** Initialise the buffer header which contains the information needed to
169 ** maintain the buffer
170 */
171 cbf_hdr[bufId].max_num_items = max_num_items;
172 cbf_hdr[bufId].item_size = item_size;
173 cbf_hdr[bufId].null_char = null_char;
174 cbf_hdr[bufId].overwrite = overwrite;
175
176 /*
177 ** The buffer is created with no elements in it.
178 */
179 cbf_hdr[bufId].num_elements = 0;
180 cbf_hdr[bufId].mfw_cb_read_pos = 0;
181 cbf_hdr[bufId].mfw_cb_write_pos = 0;
182
183 /*
184 ** Ensure the buffer is initialised with the required null character
185 */
186 memset(cbf_hdr[bufId].mfw_cb,
187 cbf_hdr[bufId].null_char,
188 item_size * max_num_items);
189
190 return (bufId);
191 }
192
193 /*
194 +--------------------------------------------------------------------+
195 | PROJECT: MMI-Framework (8417) MODULE: MFW_CBUF |
196 | STATE : code ROUTINE: (static) mfw_cbuf_delete |
197 +--------------------------------------------------------------------+
198
199
200 PURPOSE : delete a dynamically allocated buffer, freeing the memory
201 A statically allocated buffer CANNOT be released.
202
203 */
204 SHORT mfw_cbuf_delete (SHORT bufId)
205 {
206 if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
207 return (MFW_CBUF_INVALID_BUF_ID);
208
209 if (cbf_hdr[bufId].active == FALSE)
210 return (MFW_CBUF_INVALID_BUF_ID);
211
212 if (cbf_hdr[bufId].static_buf)
213 return (MFW_CBUF_INVALID_STATIC_BUF);
214
215 /*
216 ** Free the dynamically allocated memory and set buffer to inactive
217 ** all the other information is irrelevant as once the buffer is marked inactive
218 ** it cannot be used.
219 */
220 mfwFree(cbf_hdr[bufId].mfw_cb,
221 cbf_hdr[bufId].item_size * cbf_hdr[bufId].max_num_items);
222
223 cbf_hdr[bufId].active = FALSE;
224
225 return (MFW_CBUF_OK);
226 }
227
228 /*
229 +--------------------------------------------------------------------+
230 | PROJECT: MMI-Framework (8417) MODULE: MFW_CBUF |
231 | STATE : code ROUTINE: (static) mfw_cbuf_reset |
232 +--------------------------------------------------------------------+
233
234
235 PURPOSE : clears all the data from the buffer and resets the read and write pointers.
236
237 */
238 SHORT mfw_cbuf_reset (SHORT bufId)
239 {
240 if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
241 return (MFW_CBUF_INVALID_BUF_ID);
242
243 if (cbf_hdr[bufId].active == FALSE)
244 return (MFW_CBUF_INVALID_BUF_ID);
245
246 /*
247 ** The buffer is reset with no elements in it.
248 */
249 cbf_hdr[bufId].num_elements = 0;
250 cbf_hdr[bufId].mfw_cb_read_pos = 0;
251 cbf_hdr[bufId].mfw_cb_write_pos = 0;
252
253 /*
254 ** Ensure the buffer is initialised with the required null character
255 */
256 memset(cbf_hdr[bufId].mfw_cb,
257 cbf_hdr[bufId].null_char,
258 cbf_hdr[bufId].item_size * cbf_hdr[bufId].max_num_items);
259
260 return (MFW_CBUF_OK);
261 }
262
263 /*
264 +--------------------------------------------------------------------+
265 | PROJECT: MMI-Framework (8417) MODULE: MFW_CBUF |
266 | STATE : code ROUTINE: (static) mfw_cbuf_put |
267 +--------------------------------------------------------------------+
268
269
270 PURPOSE : Add an item to the appropriate circular buffer
271
272 */
273 SHORT mfw_cbuf_put (SHORT bufId, void *data_ptr)
274 {
275 if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
276 return (MFW_CBUF_INVALID_BUF_ID);
277
278 if (cbf_hdr[bufId].active == FALSE)
279 return (MFW_CBUF_INVALID_BUF_ID);
280
281 if (data_ptr == (void *)0)
282 return (MFW_CBUF_INVALID_BUF_PTR);
283
284 if (cbf_hdr[bufId].num_elements < cbf_hdr[bufId].max_num_items)
285 {
286 /*
287 ** Standard Add data ... no data lost.
288 ** Memcpy the input data into the circular buffer
289 */
290 memcpy(&cbf_hdr[bufId].mfw_cb[cbf_hdr[bufId].mfw_cb_write_pos],
291 data_ptr,
292 cbf_hdr[bufId].item_size);
293
294 /*
295 ** Move the write_pointer along to the next required position
296 */
297 cbf_hdr[bufId].mfw_cb_write_pos = (cbf_hdr[bufId].mfw_cb_write_pos + cbf_hdr[bufId].item_size) %
298 (cbf_hdr[bufId].item_size * cbf_hdr[bufId].max_num_items);
299 cbf_hdr[bufId].num_elements++;
300 return (MFW_CBUF_OK);
301 }
302 else if (cbf_hdr[bufId].overwrite)
303 {
304 /*
305 ** Overwrite Add data ... The oldest Data in the buffer is lost.
306 ** Memcpy the input data into the circular buffer
307 */
308 memcpy(&cbf_hdr[bufId].mfw_cb[cbf_hdr[bufId].mfw_cb_write_pos],
309 data_ptr,
310 cbf_hdr[bufId].item_size);
311
312 /*
313 ** Move the write_pointer along to the next required position
314 */
315 cbf_hdr[bufId].mfw_cb_write_pos = (cbf_hdr[bufId].mfw_cb_write_pos + cbf_hdr[bufId].item_size) %
316 (cbf_hdr[bufId].item_size * cbf_hdr[bufId].max_num_items);
317 /*
318 ** Move the read pointer along to the next required position as the data it points to
319 ** has been overwritten
320 */
321 cbf_hdr[bufId].mfw_cb_read_pos = (cbf_hdr[bufId].mfw_cb_read_pos + cbf_hdr[bufId].item_size) %
322 (cbf_hdr[bufId].item_size * cbf_hdr[bufId].max_num_items);
323 return (MFW_CBUF_OK_DATA_LOSS);
324 }
325 else
326 {
327 /*
328 ** The Queue is full ... return an error
329 */
330 return (MFW_CBUF_PUT_FAILED_Q_FULL);
331 }
332 }
333
334 /*
335 +--------------------------------------------------------------------+
336 | PROJECT: MMI-Framework (8417) MODULE: MFW_CBUF |
337 | STATE : code ROUTINE: (static) mfw_cbuf_get |
338 +--------------------------------------------------------------------+
339
340
341 PURPOSE : Get an event from the DTMF Q
342
343 */
344 SHORT mfw_cbuf_get (SHORT bufId, void *buffer_ptr)
345 {
346 if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
347 return (MFW_CBUF_INVALID_BUF_ID);
348
349 if (cbf_hdr[bufId].active == FALSE)
350 return (MFW_CBUF_INVALID_BUF_ID);
351
352 if (buffer_ptr == (void *)0)
353 return (MFW_CBUF_INVALID_BUF_PTR);
354
355 if (cbf_hdr[bufId].num_elements != 0)
356 {
357 /*
358 ** Copy the data from the internal buffer into the output buffer, and reset the internal buffer
359 */
360 memcpy(buffer_ptr,
361 &cbf_hdr[bufId].mfw_cb[cbf_hdr[bufId].mfw_cb_read_pos],
362 cbf_hdr[bufId].item_size);
363
364 memset(&cbf_hdr[bufId].mfw_cb[cbf_hdr[bufId].mfw_cb_read_pos],
365 cbf_hdr[bufId].null_char,
366 cbf_hdr[bufId].item_size);
367
368 /*
369 ** Move the read pointer along to the next required position
370 */
371 cbf_hdr[bufId].mfw_cb_read_pos = (cbf_hdr[bufId].mfw_cb_read_pos + cbf_hdr[bufId].item_size) %
372 (cbf_hdr[bufId].item_size * cbf_hdr[bufId].max_num_items);
373
374 cbf_hdr[bufId].num_elements--;
375
376 return (MFW_CBUF_OK);
377 }
378 else
379 {
380 /*
381 ** The Queue is empty ... put valid (null) data into the buffer and return an error
382 */
383 memset(buffer_ptr,
384 cbf_hdr[bufId].null_char,
385 cbf_hdr[bufId].item_size);
386
387 return (MFW_CBUF_BUFFER_EMPTY);
388 }
389 }
390
391
392 /*
393 +-----------------------------------------------------------------------+
394 |xnkulkar SPR-18262 |
395 |ROUTINE: SHORT mfw_cbuf_put_mode() |
396 |PURPOSE : Put the mode (Start/Stop) for the DTMF tone in queue |
397 | |
398 +-----------------------------------------------------------------------+
399 */
400
401 SHORT mfw_cbuf_put_mode (SHORT bufId,UBYTE vts_mode)
402 {
403 TRACE_FUNCTION("mfw_cbuf_put_mode()");
404
405 // Check for the validity of buffer ID and "limit" for the number of elements
406 // if ok, put the mode (Start / Stop) for the specified DTMF tone in the queue
407 if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
408 return MFW_CBUF_INVALID_BUF_ID;
409 if (cbf_hdr[bufId].num_elements >= cbf_hdr[bufId].max_num_items)
410 return MFW_CBUF_PUT_FAILED_Q_FULL;
411 cbf_hdr[bufId].vts_mode[cbf_hdr[bufId].mfw_cb_write_pos] = vts_mode;
412 return (MFW_CBUF_OK);
413 }
414
415
416 /*
417 +-----------------------------------------------------------------------+
418 |xnkulkar SPR-18262 |
419 |ROUTINE: SHORT mfw_cbuf_get_mode() |
420 |PURPOSE : Get the mode (Start/Stop) for the DTMF tone in queue |
421 | |
422 +-----------------------------------------------------------------------+
423 */
424 SHORT mfw_cbuf_get_mode (SHORT bufId)
425 {
426 TRACE_FUNCTION("mfw_cbuf_get_mode()");
427
428 // Check for the validity of buffer ID and "limit" for the number of elements
429 // if ok, return the mode (Start / Stop) for the requested DTMF tone
430 if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
431 return MFW_CBUF_INVALID_BUF_ID;
432 if (cbf_hdr[bufId].num_elements >= cbf_hdr[bufId].max_num_items)
433 return MFW_CBUF_PUT_FAILED_Q_FULL;
434 return cbf_hdr[bufId].vts_mode[cbf_hdr[bufId].mfw_cb_read_pos];
435 }
436
437 /*
438 +--------------------------------------------------------------------+
439 | PROJECT: MMI-Framework (8417) MODULE: MFW_CBUF |
440 | STATE : code ROUTINE: (static) mfw_cbuf_num_elements |
441 +--------------------------------------------------------------------+
442
443
444 PURPOSE : Get the number of events on the DTMF Q
445
446 */
447 USHORT mfw_cbuf_num_elements (SHORT bufId)
448 {
449 /*
450 ** In this function, if the buffer Id is invalid in any way, we will need to
451 ** return 0 for the number of elements and know that any other action on
452 ** the buffer will result in an error state.
453 */
454 if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
455 return (0);
456
457 if (cbf_hdr[bufId].active == FALSE)
458 return (0);
459
460 /*
461 ** Having got to here, the buffer id is valid so return the number of elements
462 */
463 return (cbf_hdr[bufId].num_elements);
464 }
465
466 static SHORT mfw_cbuf_get_free_id(void)
467 {
468 SHORT i;
469
470 for (i=0; i<MAX_CBUF_QUEUES; i++)
471 {
472 if (cbf_hdr[i].active == FALSE)
473 {
474 /*
475 ** This is the first inactive buffer, pass the index back
476 */
477 return (i);
478 }
479 }
480
481 /*
482 ** There are no inaqctive buffers, return an Error
483 */
484 return (MFW_CBUF_NO_BUFS_AVAILABLE);
485 }
486