FreeCalypso > hg > fc-tourmaline
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 |
