summaryrefslogtreecommitdiff
path: root/utilities/fsl_notifier.c
diff options
context:
space:
mode:
Diffstat (limited to 'utilities/fsl_notifier.c')
-rw-r--r--utilities/fsl_notifier.c182
1 files changed, 182 insertions, 0 deletions
diff --git a/utilities/fsl_notifier.c b/utilities/fsl_notifier.c
new file mode 100644
index 0000000..3e2744f
--- /dev/null
+++ b/utilities/fsl_notifier.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "fsl_notifier.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+status_t NOTIFIER_CreateHandle(notifier_handle_t *notifierHandle,
+ notifier_user_config_t **configs,
+ uint8_t configsNumber,
+ notifier_callback_config_t *callbacks,
+ uint8_t callbacksNumber,
+ notifier_user_function_t userFunction,
+ void *userData)
+{
+ /* Check input parameter - at least one configuration is required and userFunction must exist */
+ if ((configs == NULL) || (configsNumber == 0U) || (userFunction == NULL))
+ {
+ return kStatus_Fail;
+ }
+ /* Initialize handle structure */
+ memset(notifierHandle, 0, sizeof(notifier_handle_t));
+ /* Store references to user-defined configurations */
+ notifierHandle->configsTable = configs;
+ notifierHandle->configsNumber = configsNumber;
+ /* Store references to user-defined callback configurations */
+ if (callbacks != NULL)
+ {
+ notifierHandle->callbacksTable = callbacks;
+ notifierHandle->callbacksNumber = callbacksNumber;
+ /* If all callbacks return success, then the errorCallbackIndex is callbacksNumber */
+ notifierHandle->errorCallbackIndex = callbacksNumber;
+ }
+ notifierHandle->userFunction = userFunction;
+ notifierHandle->userData = userData;
+
+ return kStatus_Success;
+}
+
+status_t NOTIFIER_SwitchConfig(notifier_handle_t *notifierHandle, uint8_t configIndex, notifier_policy_t policy)
+{
+ uint8_t currentStaticCallback = 0U; /* Index to array of statically registered call-backs */
+ status_t returnCode = kStatus_Success; /* Function return */
+
+ notifier_notification_block_t notifyBlock; /* Callback notification block */
+ notifier_callback_config_t *callbackConfig; /* Pointer to callback configuration */
+
+ /* Set errorcallbackindex as callbacksNumber, which means no callback error now */
+ notifierHandle->errorCallbackIndex = notifierHandle->callbacksNumber;
+
+ /* Requested configuration availability check */
+ if (configIndex >= notifierHandle->configsNumber)
+ {
+ return kStatus_OutOfRange;
+ }
+
+ /* Initialization of local variables from the Notifier handle structure */
+
+ notifyBlock.policy = policy;
+ notifyBlock.targetConfig = notifierHandle->configsTable[configIndex];
+ notifyBlock.notifyType = kNOTIFIER_NotifyBefore;
+
+ /* From all statically registered call-backs... */
+ for (currentStaticCallback = 0U; currentStaticCallback < notifierHandle->callbacksNumber; currentStaticCallback++)
+ {
+ callbackConfig = &(notifierHandle->callbacksTable[currentStaticCallback]);
+ /* ...notify only those which asked to be called before the configuration switch */
+ if (((uint32_t)callbackConfig->callbackType) & kNOTIFIER_CallbackBefore)
+ {
+ /* In case that call-back returned error code mark it, store the call-back handle and eventually cancel
+ * the configuration switch */
+ if (callbackConfig->callback(&notifyBlock, callbackConfig->callbackData) != kStatus_Success)
+ {
+ returnCode = kStatus_NOTIFIER_ErrorNotificationBefore;
+ notifierHandle->errorCallbackIndex = currentStaticCallback;
+ /* If not forcing configuration switch, call all already notified call-backs to revert their state
+ * as the switch is canceled */
+ if (policy != kNOTIFIER_PolicyForcible)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ /* Set configuration */
+
+ /* In case that any call-back returned error code and policy doesn't force the configuration set, go to after
+ * switch call-backs */
+ if ((policy == kNOTIFIER_PolicyForcible) || (returnCode == kStatus_Success))
+ {
+ returnCode = notifierHandle->userFunction(notifierHandle->configsTable[configIndex], notifierHandle->userData);
+ if (returnCode != kStatus_Success)
+ {
+ return returnCode;
+ }
+ /* Update current configuration index */
+ notifierHandle->currentConfigIndex = configIndex;
+ notifyBlock.notifyType = kNOTIFIER_NotifyAfter;
+ /* From all statically registered call-backs... */
+ for (currentStaticCallback = 0U; currentStaticCallback < notifierHandle->callbacksNumber;
+ currentStaticCallback++)
+ {
+ callbackConfig = &(notifierHandle->callbacksTable[currentStaticCallback]);
+ /* ...notify only those which asked to be called after the configruation switch */
+ if (((uint32_t)callbackConfig->callbackType) & kNOTIFIER_CallbackAfter)
+ {
+ /* In case that call-back returned error code mark it and store the call-back handle */
+ if (callbackConfig->callback(&notifyBlock, callbackConfig->callbackData) != kStatus_Success)
+ {
+ returnCode = kStatus_NOTIFIER_ErrorNotificationAfter;
+ notifierHandle->errorCallbackIndex = currentStaticCallback;
+ if (policy != kNOTIFIER_PolicyForcible)
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /* End of unsuccessful switch */
+ notifyBlock.notifyType = kNOTIFIER_NotifyRecover;
+ while (currentStaticCallback--)
+ {
+ callbackConfig = &(notifierHandle->callbacksTable[currentStaticCallback]);
+ if (((uint32_t)callbackConfig->callbackType) & kNOTIFIER_CallbackBefore)
+ {
+ callbackConfig->callback(&notifyBlock, callbackConfig->callbackData);
+ }
+ }
+ }
+
+ return returnCode;
+}
+
+uint8_t NOTIFIER_GetErrorCallbackIndex(notifier_handle_t *notifierHandle)
+{
+ return notifierHandle->errorCallbackIndex;
+}