1895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/*
2895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall $License:
3895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall   Copyright 2011 InvenSense, Inc.
4895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
5895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall Licensed under the Apache License, Version 2.0 (the "License");
6895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall you may not use this file except in compliance with the License.
7895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall You may obtain a copy of the License at
8895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
9895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall http://www.apache.org/licenses/LICENSE-2.0
10895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
11895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall Unless required by applicable law or agreed to in writing, software
12895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall distributed under the License is distributed on an "AS IS" BASIS,
13895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall See the License for the specific language governing permissions and
15895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall limitations under the License.
16895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall  $
17895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall */
18895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/*******************************************************************************
19895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *
20895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * $Id: mlstates.c 5629 2011-06-11 03:13:08Z mcaramello $
21895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *
22895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *******************************************************************************/
23895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
24895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/**
25895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @defgroup MLSTATES
26895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @brief  Basic state machine definition and support for the Motion Library.
27895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *
28895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @{
29895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *      @file mlstates.c
30895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *      @brief The Motion Library state machine definition.
31895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall */
32895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
33895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#define ML_C
34895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
35895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/* ------------------ */
36895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/* - Include Files. - */
37895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/* ------------------ */
38895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
39895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include <stdio.h>
40895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include <string.h>
41895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
42895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "mlstates.h"
43895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "mltypes.h"
44895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "mlinclude.h"
45895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "ml.h"
46895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include "mlos.h"
47895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
48895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#include <log.h>
49895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#undef MPL_LOG_TAG
50895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#define MPL_LOG_TAG "MPL-mlstates"
51895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
52895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#define _stateDebug(x)          //{x}
53895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
54895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall#define MAX_STATE_CHANGE_PROCESSES (8)
55895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
56895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallstruct state_callback_obj {
57895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    int_fast8_t numStateChangeCallbacks;
58895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    HANDLE mutex;
59895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    state_change_callback_t stateChangeCallbacks[MAX_STATE_CHANGE_PROCESSES];
60895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall};
61895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
62895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallstatic struct state_callback_obj sStateChangeCallbacks = { 0 };
63895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
64895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/* --------------- */
65895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/* -  Functions. - */
66895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/* --------------- */
67895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
68895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallstatic inv_error_t inv_init_state_callbacks(void)
69895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
70895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    memset(&sStateChangeCallbacks, 0, sizeof(sStateChangeCallbacks));
71895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return inv_create_mutex(&sStateChangeCallbacks.mutex);
72895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
73895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
74895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallstatic inv_error_t MLStateCloseCallbacks(void)
75895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
76895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_error_t result;
77895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result = inv_destroy_mutex(sStateChangeCallbacks.mutex);
78895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    memset(&sStateChangeCallbacks, 0, sizeof(sStateChangeCallbacks));
79895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return result;
80895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
81895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
82895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/**
83895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @internal
84895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @brief  return a string containing the label assigned to the given state.
85895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @param  state   The state of which the label has to be returned.
86895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @return A string containing the state label.
87895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall**/
88895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallchar *inv_state_name(unsigned char state)
89895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
90895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    switch (state) {
91895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    case INV_STATE_SERIAL_CLOSED:
92895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return INV_STATE_NAME(INV_STATE_SERIAL_CLOSED);
93895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        break;
94895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    case INV_STATE_SERIAL_OPENED:
95895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return INV_STATE_NAME(INV_STATE_SERIAL_OPENED);
96895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        break;
97895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    case INV_STATE_DMP_OPENED:
98895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return INV_STATE_NAME(INV_STATE_DMP_OPENED);
99895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        break;
100895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    case INV_STATE_DMP_STARTED:
101895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return INV_STATE_NAME(INV_STATE_DMP_STARTED);
102895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        break;
103895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    default:
104895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return NULL;
105895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
106895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
107895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
108895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/**
109895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @internal
110895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @brief  Perform a transition from the current state to newState.
111895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          Check for the correctness of the transition.
112895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          Print out an error message if the transition is illegal .
113895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          This routine is also called if a certain normally constant parameters
114895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          are changed such as the FIFO Rate.
115895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @param  newState    state we are transitioning to.
116895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @return
117895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall**/
118895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallinv_error_t inv_state_transition(unsigned char newState)
119895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
120895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_error_t result = INV_SUCCESS;
121895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
122895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (newState == INV_STATE_SERIAL_CLOSED) {
123895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        // Always allow transition to closed
124895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } else if (newState == INV_STATE_SERIAL_OPENED) {
125895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        inv_init_state_callbacks(); // Always allow first transition to start over
126895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } else if (((newState == INV_STATE_DMP_OPENED) &&
127895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                ((inv_params_obj.state == INV_STATE_SERIAL_OPENED) ||
128895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                 (inv_params_obj.state == INV_STATE_DMP_STARTED)))
129895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall               ||
130895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall               ((newState == INV_STATE_DMP_STARTED) &&
131895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                (inv_params_obj.state == INV_STATE_DMP_OPENED))) {
132895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        // Valid transitions but no special action required
133895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } else {
134895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        // All other combinations are illegal
135895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        MPL_LOGE("Error : illegal state transition from %s to %s\n",
136895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                 inv_state_name(inv_params_obj.state),
137895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                 inv_state_name(newState));
138895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        result = INV_ERROR_SM_TRANSITION;
139895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
140895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
141895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (result == INV_SUCCESS) {
142895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        _stateDebug(MPL_LOGV
143895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    ("ML State transition from %s to %s\n",
144895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                     inv_state_name(inv_params_obj.state),
145895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                     inv_state_name(newState)));
146895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        result = inv_run_state_callbacks(newState);
147895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (INV_SUCCESS == result && newState == INV_STATE_SERIAL_CLOSED) {
148895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            MLStateCloseCallbacks();
149895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
150895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        inv_params_obj.state = newState;
151895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
152895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return result;
153895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
154895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
155895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/**
156895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @internal
157895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *  @brief  To be moved in mlstates.c
158895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall**/
159895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallunsigned char inv_get_state(void)
160895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
161895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return (inv_params_obj.state);
162895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
163895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
164895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/**
165895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * @internal
166895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * @brief   This registers a function to be called each time the state
167895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          changes. It may also be called when the FIFO Rate is changed.
168895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          It will be called at the start of a state change before the
169895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          state change has taken place. See Also inv_unregister_state_callback()
170895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          The FIFO does not have to be on for this callback.
171895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * @param func Function to be called when a DMP interrupt occurs.
172895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * @return INV_SUCCESS or non-zero error code.
173895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall */
174895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
175895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallinv_error_t inv_register_state_callback(state_change_callback_t callback)
176895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
177895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    INVENSENSE_FUNC_START;
178895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    int kk;
179895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_error_t result;
180895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
181895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result = inv_lock_mutex(sStateChangeCallbacks.mutex);
182895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (INV_SUCCESS != result) {
183895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return result;
184895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
185895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    // Make sure we have not filled up our number of allowable callbacks
186895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (sStateChangeCallbacks.numStateChangeCallbacks <
187895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        MAX_STATE_CHANGE_PROCESSES) {
188895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        // Make sure we haven't registered this function already
189895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        for (kk = 0; kk < sStateChangeCallbacks.numStateChangeCallbacks; ++kk) {
190895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            if (sStateChangeCallbacks.stateChangeCallbacks[kk] == callback) {
191895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                result = INV_ERROR_INVALID_PARAMETER;
192895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                break;
193895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            }
194895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
195895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
196895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (INV_SUCCESS == result) {
197895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            // Add new callback
198895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            sStateChangeCallbacks.stateChangeCallbacks[sStateChangeCallbacks.
199895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                                                       numStateChangeCallbacks]
200895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                = callback;
201895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            sStateChangeCallbacks.numStateChangeCallbacks++;
202895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
203895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    } else {
204895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        result = INV_ERROR_MEMORY_EXAUSTED;
205895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
206895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
207895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_unlock_mutex(sStateChangeCallbacks.mutex);
208895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return result;
209895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
210895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
211895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall/**
212895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * @internal
213895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * @brief   This unregisters a function to be called each time the state
214895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          changes. See Also inv_register_state_callback()
215895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall *          The FIFO does not have to be on for this callback.
216895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall * @return INV_SUCCESS or non-zero error code.
217895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall */
218895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallinv_error_t inv_unregister_state_callback(state_change_callback_t callback)
219895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
220895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    INVENSENSE_FUNC_START;
221895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    int kk, jj;
222895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_error_t result;
223895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
224895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result = inv_lock_mutex(sStateChangeCallbacks.mutex);
225895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (INV_SUCCESS != result) {
226895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return result;
227895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
228895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    // Make sure we haven't registered this function already
229895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result = INV_ERROR_INVALID_PARAMETER;
230895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    for (kk = 0; kk < sStateChangeCallbacks.numStateChangeCallbacks; ++kk) {
231895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (sStateChangeCallbacks.stateChangeCallbacks[kk] == callback) {
232895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            for (jj = kk + 1;
233895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                 jj < sStateChangeCallbacks.numStateChangeCallbacks; ++jj) {
234895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                sStateChangeCallbacks.stateChangeCallbacks[jj - 1] =
235895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                    sStateChangeCallbacks.stateChangeCallbacks[jj];
236895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            }
237895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            sStateChangeCallbacks.numStateChangeCallbacks--;
238895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            result = INV_SUCCESS;
239895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            break;
240895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
241895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
242895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
243895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_unlock_mutex(sStateChangeCallbacks.mutex);
244895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return result;
245895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
246895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
247895401859313187f15a800e62d43e6bcbf48fadaJP Abgrallinv_error_t inv_run_state_callbacks(unsigned char newState)
248895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall{
249895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    int kk;
250895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_error_t result;
251895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
252895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    result = inv_lock_mutex(sStateChangeCallbacks.mutex);
253895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    if (INV_SUCCESS != result) {
254895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        MPL_LOGE("MLOsLockMutex returned %d\n", result);
255895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        return result;
256895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
257895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
258895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    for (kk = 0; kk < sStateChangeCallbacks.numStateChangeCallbacks; ++kk) {
259895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        if (sStateChangeCallbacks.stateChangeCallbacks[kk]) {
260895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            result = sStateChangeCallbacks.stateChangeCallbacks[kk] (newState);
261895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            if (INV_SUCCESS != result) {
262895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall                break;          // Can't return, must release mutex
263895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall            }
264895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall        }
265895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    }
266895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall
267895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    inv_unlock_mutex(sStateChangeCallbacks.mutex);
268895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall    return result;
269895401859313187f15a800e62d43e6bcbf48fadaJP Abgrall}
270