diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ui/mfw/mfw_utils.c	Fri Oct 16 06:33:10 2020 +0000
@@ -0,0 +1,486 @@
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417) 	$Workfile:: mfw_utils.c			$|
+| $Author:: NDH						$Revision:: 1					$|
+| CREATED: 6.1.2003		       		$Modtime:: 10.04.00 14:58		$|
+| STATE  : code														$|
++--------------------------------------------------------------------+
+
+   MODULE  : MFW_UTILS
+
+   PURPOSE : This modul contains General Functional Utilities.
+
+   HISTORY:
+	Oct 04, 2004    REF: CRR 25519     Deepa M.D
+	Bug:Re-align structure members in MFW
+	Fix:Structure elements have been  realigned to avoid the structure padding
+
+   Jun 05, 2004	REF: CRR 18262  NISHIKANT KULKARNI 
+   Description: The sample sends a STOP DTMF message without release of the key by the user
+   Solution: Instead of sending DTMF commands in "VTS_MOD_Auto" mode, on key press DTMF tone is started
+  		   using VTS_MOD_ManStart and on key release DTMF tone is stopped using VTS_MOD_ManStop mode.
+
+*/
+
+#include <string.h>
+
+
+#if defined (NEW_FRAME)
+
+#include "typedefs.h"
+#include "vsi.h"
+#include "pei.h"
+#include "custom.h"
+#include "gsm.h"
+
+#else
+
+#include "STDDEFS.H"
+#include "custom.h"
+#include "gsm.h"
+#include "vsi.h"
+
+#endif
+
+#include "mfw_mfw.h"
+#include "mfw_utils.h"
+
+#include "cus_aci.h"
+#include "prim.h"
+#ifndef PCM_2_FFS
+#include "pcm.h"
+#endif
+
+
+// xnkulkar SPR-18262: This length of array for storing DTMF mode (Start/Stop), is equal to the number 
+// of DTMF tone requests that can be stored in queue.
+#define MAX_DTMF_Q_ENTRIES 50
+/***************************Go-lite Optimization changes start***********************/
+//Oct 04, 2004    REF: CRR 25519     Deepa M.D
+//Structure elements (T_MFW_CBUF_HEADER)are realigned to avoid the structure padding
+typedef struct
+{	//xnkulkar SPR-18262: This member is used to store the mode for various DTMF tones present in queue to be sent.
+	UBYTE vts_mode[MAX_DTMF_Q_ENTRIES];
+	USHORT item_size;
+	UBYTE *mfw_cb;
+	ULONG mfw_cb_read_pos;
+	ULONG mfw_cb_write_pos;
+	USHORT num_elements;
+	USHORT max_num_items;
+	UBYTE null_char;
+	UBYTE overwrite;
+	UBYTE static_buf;
+	UBYTE active;
+} T_MFW_CBUF_HEADER;
+/***************************Go-lite Optimization changes end***********************/
+
+static T_MFW_CBUF_HEADER cbf_hdr[MAX_CBUF_QUEUES];
+static UBYTE cbf_num_of_buffers;
+
+
+/*
+** Static Function Prototypes
+*/
+static SHORT mfw_cbuf_get_free_id(void);
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417) 	MODULE: MFW_CBUF	             |
+| STATE  : code 			ROUTINE: (static) mfw_cbuf_init          |
++--------------------------------------------------------------------+
+
+
+   PURPOSE :  Create and Initialise the Circular Buffer
+
+*/
+SHORT mfw_cbuf_create (USHORT max_num_items, USHORT item_size,
+						 UBYTE overwrite, UBYTE null_char,
+						 UBYTE static_buf, void *buffer_ptr)
+{
+	SHORT bufId;
+	
+	if (cbf_num_of_buffers < MAX_CBUF_QUEUES)
+	{
+		/*
+		** Get the first available Id for a free buffer
+		*/
+		bufId = mfw_cbuf_get_free_id();
+		if (bufId == MFW_CBUF_NO_BUFS_AVAILABLE)
+			return (MFW_CBUF_NO_BUFS_AVAILABLE);
+	}
+	else
+	{
+		/*
+		** return -1 as an indication that there are no more buffer handles available
+		*/
+		return (MFW_CBUF_NO_BUFS_AVAILABLE);
+	}
+
+	/*
+	** We now have a valid bufferId but check the validity of the incoming parameters
+	** before we allocate the buffer.
+	*/
+	if (item_size == 0)
+		return (MFW_CBUF_INVALID_ITEM_SIZE);
+
+	if (max_num_items == 0)
+		return (MFW_CBUF_INVALID_MAX_ITEMS);
+
+	if ((static_buf) && (buffer_ptr == (void *)0))
+		return (MFW_CBUF_INVALID_BUF_PTR);
+
+	if ((!static_buf) && (buffer_ptr != (void *)0))
+		return (MFW_CBUF_INVALID_BUF_PTR);
+	
+	/*
+	** Set the selected buffer to active
+	*/
+	cbf_hdr[bufId].active = TRUE;
+
+	if (!static_buf)
+	{
+		/*
+		** If the buffer isn't static, then get the dynamic memory for it.
+		*/
+		cbf_hdr[bufId].mfw_cb = mfwAlloc(item_size * max_num_items);
+		cbf_hdr[bufId].static_buf = FALSE;
+
+		if (cbf_hdr[bufId].mfw_cb == (void *)0)
+		{
+			/*
+			** The memory Allocation failed, mark the buffer as inactive and return an error
+			*/
+			cbf_hdr[bufId].active = FALSE;
+			return (MFW_CBUF_MEM_ALLOC_FAILURE);
+		}
+	}
+	else
+	{
+		/*
+		** If the buffer is static, the calling function will have provided a
+		** pointer to the buffer to be used.
+		*/
+		cbf_hdr[bufId].mfw_cb = (UBYTE *)buffer_ptr;
+		cbf_hdr[bufId].static_buf = TRUE;
+	}
+
+	/*
+	** Initialise the buffer header which contains the information needed to
+	** maintain the buffer
+	*/
+	cbf_hdr[bufId].max_num_items = max_num_items;
+	cbf_hdr[bufId].item_size = item_size;
+	cbf_hdr[bufId].null_char = null_char;
+	cbf_hdr[bufId].overwrite = overwrite;
+
+	/*
+	** The buffer is created with no elements in it.
+	*/
+	cbf_hdr[bufId].num_elements = 0;
+	cbf_hdr[bufId].mfw_cb_read_pos = 0;
+	cbf_hdr[bufId].mfw_cb_write_pos = 0;
+
+	/*
+	** Ensure the buffer is initialised with the required null character
+	*/
+	memset(cbf_hdr[bufId].mfw_cb,
+			cbf_hdr[bufId].null_char,
+			item_size * max_num_items);
+
+	return (bufId);
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417) 	MODULE: MFW_CBUF	             |
+| STATE  : code 			ROUTINE: (static) mfw_cbuf_delete	     |
++--------------------------------------------------------------------+
+
+
+   PURPOSE :  delete a dynamically allocated buffer, freeing the memory
+   			  A statically allocated buffer CANNOT be released.
+
+*/
+SHORT mfw_cbuf_delete (SHORT bufId)
+{
+	if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
+		return (MFW_CBUF_INVALID_BUF_ID);
+
+	if (cbf_hdr[bufId].active == FALSE)
+		return (MFW_CBUF_INVALID_BUF_ID);
+
+	if (cbf_hdr[bufId].static_buf)
+		return (MFW_CBUF_INVALID_STATIC_BUF);
+
+	/*
+	** Free the dynamically allocated memory and set buffer to inactive
+	** all the other information is irrelevant as once the buffer is marked inactive
+	** it cannot be used.
+	*/
+	mfwFree(cbf_hdr[bufId].mfw_cb,
+			 cbf_hdr[bufId].item_size * cbf_hdr[bufId].max_num_items);
+
+	cbf_hdr[bufId].active = FALSE;
+
+	return (MFW_CBUF_OK);
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417) 	MODULE: MFW_CBUF	             |
+| STATE  : code 			ROUTINE: (static) mfw_cbuf_reset	     |
++--------------------------------------------------------------------+
+
+
+   PURPOSE :  clears all the data from the buffer and resets the read and write pointers.
+
+*/
+SHORT mfw_cbuf_reset (SHORT bufId)
+{
+	if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
+		return (MFW_CBUF_INVALID_BUF_ID);
+
+	if (cbf_hdr[bufId].active == FALSE)
+		return (MFW_CBUF_INVALID_BUF_ID);
+
+	/*
+	** The buffer is reset with no elements in it.
+	*/
+	cbf_hdr[bufId].num_elements = 0;
+	cbf_hdr[bufId].mfw_cb_read_pos = 0;
+	cbf_hdr[bufId].mfw_cb_write_pos = 0;
+
+	/*
+	** Ensure the buffer is initialised with the required null character
+	*/
+	memset(cbf_hdr[bufId].mfw_cb,
+			cbf_hdr[bufId].null_char,
+			cbf_hdr[bufId].item_size * cbf_hdr[bufId].max_num_items);
+
+	return (MFW_CBUF_OK);
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417) 	MODULE: MFW_CBUF	             |
+| STATE  : code 			ROUTINE: (static) mfw_cbuf_put	         |
++--------------------------------------------------------------------+
+
+
+   PURPOSE :  Add an item to the appropriate circular buffer
+
+*/
+SHORT mfw_cbuf_put (SHORT bufId, void *data_ptr)
+{
+	if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
+		return (MFW_CBUF_INVALID_BUF_ID);
+
+	if (cbf_hdr[bufId].active == FALSE)
+		return (MFW_CBUF_INVALID_BUF_ID);
+
+	if (data_ptr == (void *)0)
+		return (MFW_CBUF_INVALID_BUF_PTR);
+
+	if (cbf_hdr[bufId].num_elements < cbf_hdr[bufId].max_num_items)
+	{
+		/*
+		** Standard Add data ... no data lost.
+		** Memcpy the input data into the circular buffer
+		*/
+		memcpy(&cbf_hdr[bufId].mfw_cb[cbf_hdr[bufId].mfw_cb_write_pos],
+				data_ptr,
+				cbf_hdr[bufId].item_size);
+
+		/*
+		** Move the write_pointer along to the next required position
+		*/
+		cbf_hdr[bufId].mfw_cb_write_pos = (cbf_hdr[bufId].mfw_cb_write_pos + cbf_hdr[bufId].item_size) %
+										(cbf_hdr[bufId].item_size * cbf_hdr[bufId].max_num_items);
+		cbf_hdr[bufId].num_elements++;
+		return (MFW_CBUF_OK);
+	}
+	else if (cbf_hdr[bufId].overwrite)
+	{
+		/*
+		** Overwrite Add data ... The oldest Data in the buffer is lost.
+		** Memcpy the input data into the circular buffer
+		*/
+		memcpy(&cbf_hdr[bufId].mfw_cb[cbf_hdr[bufId].mfw_cb_write_pos],
+				data_ptr,
+				cbf_hdr[bufId].item_size);
+
+		/*
+		** Move the write_pointer along to the next required position
+		*/
+		cbf_hdr[bufId].mfw_cb_write_pos = (cbf_hdr[bufId].mfw_cb_write_pos + cbf_hdr[bufId].item_size) %
+										(cbf_hdr[bufId].item_size * cbf_hdr[bufId].max_num_items);
+		/*
+		** Move the read pointer along to the next required position as the data it points to
+		** has been overwritten
+		*/
+		cbf_hdr[bufId].mfw_cb_read_pos = (cbf_hdr[bufId].mfw_cb_read_pos + cbf_hdr[bufId].item_size) %
+									(cbf_hdr[bufId].item_size * cbf_hdr[bufId].max_num_items);
+		return (MFW_CBUF_OK_DATA_LOSS);
+	}
+	else
+	{
+		/*
+		** The Queue is full ... return an error
+		*/
+		return (MFW_CBUF_PUT_FAILED_Q_FULL);
+	}
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417) 	MODULE: MFW_CBUF	             |
+| STATE  : code 			ROUTINE: (static) mfw_cbuf_get	         |
++--------------------------------------------------------------------+
+
+
+   PURPOSE :  Get an event from the DTMF Q
+
+*/
+SHORT mfw_cbuf_get (SHORT bufId, void *buffer_ptr)
+{
+	if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
+		return (MFW_CBUF_INVALID_BUF_ID);
+
+	if (cbf_hdr[bufId].active == FALSE)
+		return (MFW_CBUF_INVALID_BUF_ID);
+
+	if (buffer_ptr == (void *)0)
+		return (MFW_CBUF_INVALID_BUF_PTR);
+
+	if (cbf_hdr[bufId].num_elements != 0)
+	{
+		/*
+		** Copy the data from the internal buffer into the output buffer, and reset the internal buffer
+		*/
+		memcpy(buffer_ptr,
+				 &cbf_hdr[bufId].mfw_cb[cbf_hdr[bufId].mfw_cb_read_pos],
+				 cbf_hdr[bufId].item_size);
+		
+		memset(&cbf_hdr[bufId].mfw_cb[cbf_hdr[bufId].mfw_cb_read_pos],
+				cbf_hdr[bufId].null_char,
+				cbf_hdr[bufId].item_size);
+		
+		/*
+		** Move the read pointer along to the next required position
+		*/
+		cbf_hdr[bufId].mfw_cb_read_pos = (cbf_hdr[bufId].mfw_cb_read_pos + cbf_hdr[bufId].item_size) %
+									(cbf_hdr[bufId].item_size * cbf_hdr[bufId].max_num_items);
+
+		cbf_hdr[bufId].num_elements--;
+
+		return (MFW_CBUF_OK);
+	}
+	else
+	{
+		/*
+		** The Queue is empty ... put valid (null) data into the buffer and return an error
+		*/
+		memset(buffer_ptr,
+				cbf_hdr[bufId].null_char,
+				cbf_hdr[bufId].item_size);
+
+		return (MFW_CBUF_BUFFER_EMPTY);
+	}
+}
+
+
+/*
++-----------------------------------------------------------------------+
+|xnkulkar SPR-18262														 |
+|ROUTINE: SHORT mfw_cbuf_put_mode()										 |
+|PURPOSE :  Put the mode (Start/Stop) for the DTMF tone in queue					 |
+|                   												 				 |
++-----------------------------------------------------------------------+
+*/
+
+SHORT  mfw_cbuf_put_mode (SHORT bufId,UBYTE vts_mode)
+{
+	TRACE_FUNCTION("mfw_cbuf_put_mode()");
+	
+	// Check for the validity of buffer ID and "limit" for the number of elements
+	// if ok, put the mode (Start / Stop) for the specified DTMF tone in the queue
+	if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
+		return MFW_CBUF_INVALID_BUF_ID;
+	if (cbf_hdr[bufId].num_elements >= cbf_hdr[bufId].max_num_items)
+		return MFW_CBUF_PUT_FAILED_Q_FULL;
+	cbf_hdr[bufId].vts_mode[cbf_hdr[bufId].mfw_cb_write_pos] = vts_mode;
+	return (MFW_CBUF_OK);
+}
+
+
+/*
++-----------------------------------------------------------------------+
+|xnkulkar SPR-18262														 |
+|ROUTINE: SHORT mfw_cbuf_get_mode()										 |
+|PURPOSE :  Get the mode (Start/Stop) for the DTMF tone in queue					 |
+|                 			 													 | 			
++-----------------------------------------------------------------------+
+*/
+SHORT  mfw_cbuf_get_mode  (SHORT bufId)
+{
+	TRACE_FUNCTION("mfw_cbuf_get_mode()");
+
+	// Check for the validity of buffer ID and "limit" for the number of elements
+	// if ok,  return the mode (Start / Stop) for the requested DTMF tone
+	if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
+		return MFW_CBUF_INVALID_BUF_ID;
+	if (cbf_hdr[bufId].num_elements >= cbf_hdr[bufId].max_num_items)
+		return MFW_CBUF_PUT_FAILED_Q_FULL;
+	return cbf_hdr[bufId].vts_mode[cbf_hdr[bufId].mfw_cb_read_pos];
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT: MMI-Framework (8417) 	MODULE: MFW_CBUF	             |
+| STATE  : code 			ROUTINE: (static) mfw_cbuf_num_elements  |
++--------------------------------------------------------------------+
+
+
+   PURPOSE :  Get the number of events on the DTMF Q
+
+*/
+USHORT mfw_cbuf_num_elements (SHORT bufId)
+{
+	/*
+	** In this function, if the buffer Id is invalid in any way, we will need to
+	** return 0 for the number of elements and know that any other action on
+	** the buffer will result in an error state.
+	*/
+	if ((bufId < 0) || (bufId >= MAX_CBUF_QUEUES))
+		return (0);
+
+	if (cbf_hdr[bufId].active == FALSE)
+		return (0);
+
+	/*
+	** Having got to here, the buffer id is valid so return the number of elements
+	*/
+	return (cbf_hdr[bufId].num_elements);
+}
+
+static SHORT mfw_cbuf_get_free_id(void)
+{
+	SHORT i;
+
+	for (i=0; i<MAX_CBUF_QUEUES; i++)
+	{
+		if (cbf_hdr[i].active == FALSE)
+		{
+			/*
+			** This is the first inactive buffer, pass the index back
+			*/
+			return (i);
+		}
+	}
+
+	/*
+	** There are no inaqctive buffers, return an Error
+	*/
+	return (MFW_CBUF_NO_BUFS_AVAILABLE);
+}
+