Changes to enabled on-line compiler

Committer:
JMF
Date:
Wed May 30 20:59:51 2018 +0000
Revision:
0:082731ede69f
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 0:082731ede69f 1 /*
JMF 0:082731ede69f 2 * Copyright 2015-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
JMF 0:082731ede69f 3 *
JMF 0:082731ede69f 4 * Licensed under the Apache License, Version 2.0 (the "License").
JMF 0:082731ede69f 5 * You may not use this file except in compliance with the License.
JMF 0:082731ede69f 6 * A copy of the License is located at
JMF 0:082731ede69f 7 *
JMF 0:082731ede69f 8 * http://aws.amazon.com/apache2.0
JMF 0:082731ede69f 9 *
JMF 0:082731ede69f 10 * or in the "license" file accompanying this file. This file is distributed
JMF 0:082731ede69f 11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
JMF 0:082731ede69f 12 * express or implied. See the License for the specific language governing
JMF 0:082731ede69f 13 * permissions and limitations under the License.
JMF 0:082731ede69f 14 */
JMF 0:082731ede69f 15
JMF 0:082731ede69f 16 // Based on Eclipse Paho.
JMF 0:082731ede69f 17 /*******************************************************************************
JMF 0:082731ede69f 18 * Copyright (c) 2014 IBM Corp.
JMF 0:082731ede69f 19 *
JMF 0:082731ede69f 20 * All rights reserved. This program and the accompanying materials
JMF 0:082731ede69f 21 * are made available under the terms of the Eclipse Public License v1.0
JMF 0:082731ede69f 22 * and Eclipse Distribution License v1.0 which accompany this distribution.
JMF 0:082731ede69f 23 *
JMF 0:082731ede69f 24 * The Eclipse Public License is available at
JMF 0:082731ede69f 25 * http://www.eclipse.org/legal/epl-v10.html
JMF 0:082731ede69f 26 * and the Eclipse Distribution License is available at
JMF 0:082731ede69f 27 * http://www.eclipse.org/org/documents/edl-v10.php.
JMF 0:082731ede69f 28 *
JMF 0:082731ede69f 29 * Contributors:
JMF 0:082731ede69f 30 * Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation
JMF 0:082731ede69f 31 *******************************************************************************/
JMF 0:082731ede69f 32
JMF 0:082731ede69f 33 /**
JMF 0:082731ede69f 34 * @file aws_iot_mqtt_client_yield.c
JMF 0:082731ede69f 35 * @brief MQTT client yield API definitions
JMF 0:082731ede69f 36 */
JMF 0:082731ede69f 37
JMF 0:082731ede69f 38 #ifdef __cplusplus
JMF 0:082731ede69f 39 extern "C" {
JMF 0:082731ede69f 40 #endif
JMF 0:082731ede69f 41
JMF 0:082731ede69f 42 #include "aws_iot_mqtt_client_common_internal.h"
JMF 0:082731ede69f 43
JMF 0:082731ede69f 44 /**
JMF 0:082731ede69f 45 * This is for the case when the aws_iot_mqtt_internal_send_packet Fails.
JMF 0:082731ede69f 46 */
JMF 0:082731ede69f 47 static void _aws_iot_mqtt_force_client_disconnect(AWS_IoT_Client *pClient) {
JMF 0:082731ede69f 48 pClient->clientStatus.clientState = CLIENT_STATE_DISCONNECTED_ERROR;
JMF 0:082731ede69f 49 pClient->networkStack.disconnect(&(pClient->networkStack));
JMF 0:082731ede69f 50 pClient->networkStack.destroy(&(pClient->networkStack));
JMF 0:082731ede69f 51 }
JMF 0:082731ede69f 52
JMF 0:082731ede69f 53 static IoT_Error_t _aws_iot_mqtt_handle_disconnect(AWS_IoT_Client *pClient) {
JMF 0:082731ede69f 54 IoT_Error_t rc;
JMF 0:082731ede69f 55
JMF 0:082731ede69f 56 FUNC_ENTRY;
JMF 0:082731ede69f 57 //printf("JMF: called aws_iot_mqtt_handle_disconnect\n");
JMF 0:082731ede69f 58 rc = aws_iot_mqtt_disconnect(pClient);
JMF 0:082731ede69f 59 if(rc != AWS_SUCCESS) {
JMF 0:082731ede69f 60 // If the aws_iot_mqtt_internal_send_packet prevents us from sending a disconnect packet then we have to clean the stack
JMF 0:082731ede69f 61 _aws_iot_mqtt_force_client_disconnect(pClient);
JMF 0:082731ede69f 62 }
JMF 0:082731ede69f 63
JMF 0:082731ede69f 64 if(NULL != pClient->clientData.disconnectHandler) {
JMF 0:082731ede69f 65 pClient->clientData.disconnectHandler(pClient, pClient->clientData.disconnectHandlerData);
JMF 0:082731ede69f 66 }
JMF 0:082731ede69f 67
JMF 0:082731ede69f 68 /* Reset to 0 since this was not a manual disconnect */
JMF 0:082731ede69f 69 pClient->clientStatus.clientState = CLIENT_STATE_DISCONNECTED_ERROR;
JMF 0:082731ede69f 70 //printf("JMF: %s:%d\n",__FILE__,__LINE__);
JMF 0:082731ede69f 71 FUNC_EXIT_RC(NETWORK_DISCONNECTED_ERROR);
JMF 0:082731ede69f 72 }
JMF 0:082731ede69f 73
JMF 0:082731ede69f 74
JMF 0:082731ede69f 75 static IoT_Error_t _aws_iot_mqtt_handle_reconnect(AWS_IoT_Client *pClient) {
JMF 0:082731ede69f 76 IoT_Error_t rc;
JMF 0:082731ede69f 77
JMF 0:082731ede69f 78 FUNC_ENTRY;
JMF 0:082731ede69f 79
JMF 0:082731ede69f 80 if(!has_timer_expired(&(pClient->reconnectDelayTimer))) {
JMF 0:082731ede69f 81 /* awsTimer has not expired. Not time to attempt reconnect yet.
JMF 0:082731ede69f 82 * Return attempting reconnect */
JMF 0:082731ede69f 83 FUNC_EXIT_RC(NETWORK_ATTEMPTING_RECONNECT);
JMF 0:082731ede69f 84 }
JMF 0:082731ede69f 85
JMF 0:082731ede69f 86 rc = NETWORK_PHYSICAL_LAYER_DISCONNECTED;
JMF 0:082731ede69f 87 if(NULL != pClient->networkStack.isConnected) {
JMF 0:082731ede69f 88 rc = pClient->networkStack.isConnected(&(pClient->networkStack));
JMF 0:082731ede69f 89 }
JMF 0:082731ede69f 90
JMF 0:082731ede69f 91 if(NETWORK_PHYSICAL_LAYER_CONNECTED == rc) {
JMF 0:082731ede69f 92 rc = aws_iot_mqtt_attempt_reconnect(pClient);
JMF 0:082731ede69f 93 if(NETWORK_RECONNECTED == rc) {
JMF 0:082731ede69f 94 rc = aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_CONNECTED_IDLE,
JMF 0:082731ede69f 95 CLIENT_STATE_CONNECTED_YIELD_IN_PROGRESS);
JMF 0:082731ede69f 96 if(AWS_SUCCESS != rc) {
JMF 0:082731ede69f 97 FUNC_EXIT_RC(rc);
JMF 0:082731ede69f 98 }
JMF 0:082731ede69f 99 FUNC_EXIT_RC(NETWORK_RECONNECTED);
JMF 0:082731ede69f 100 }
JMF 0:082731ede69f 101 }
JMF 0:082731ede69f 102
JMF 0:082731ede69f 103 pClient->clientData.currentReconnectWaitInterval *= 2;
JMF 0:082731ede69f 104
JMF 0:082731ede69f 105 if(AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL < pClient->clientData.currentReconnectWaitInterval) {
JMF 0:082731ede69f 106 FUNC_EXIT_RC(NETWORK_RECONNECT_TIMED_OUT_ERROR);
JMF 0:082731ede69f 107 }
JMF 0:082731ede69f 108 countdown_ms(&(pClient->reconnectDelayTimer), pClient->clientData.currentReconnectWaitInterval);
JMF 0:082731ede69f 109 FUNC_EXIT_RC(rc);
JMF 0:082731ede69f 110 }
JMF 0:082731ede69f 111
JMF 0:082731ede69f 112 static IoT_Error_t _aws_iot_mqtt_keep_alive(AWS_IoT_Client *pClient) {
JMF 0:082731ede69f 113 IoT_Error_t rc = AWS_SUCCESS;
JMF 0:082731ede69f 114 awsTimer timer;
JMF 0:082731ede69f 115 size_t serialized_len;
JMF 0:082731ede69f 116
JMF 0:082731ede69f 117 FUNC_ENTRY;
JMF 0:082731ede69f 118
JMF 0:082731ede69f 119 if(NULL == pClient) {
JMF 0:082731ede69f 120 FUNC_EXIT_RC(NULL_VALUE_ERROR);
JMF 0:082731ede69f 121 }
JMF 0:082731ede69f 122
JMF 0:082731ede69f 123 if(0 == pClient->clientData.keepAliveInterval) {
JMF 0:082731ede69f 124 FUNC_EXIT_RC(AWS_SUCCESS);
JMF 0:082731ede69f 125 }
JMF 0:082731ede69f 126
JMF 0:082731ede69f 127 if(!has_timer_expired(&pClient->pingTimer)) {
JMF 0:082731ede69f 128 FUNC_EXIT_RC(AWS_SUCCESS);
JMF 0:082731ede69f 129 }
JMF 0:082731ede69f 130
JMF 0:082731ede69f 131 if(pClient->clientStatus.isPingOutstanding) {
JMF 0:082731ede69f 132 //printf("JMF1\n");
JMF 0:082731ede69f 133 rc = _aws_iot_mqtt_handle_disconnect(pClient);
JMF 0:082731ede69f 134 FUNC_EXIT_RC(rc);
JMF 0:082731ede69f 135 }
JMF 0:082731ede69f 136
JMF 0:082731ede69f 137 /* there is no ping outstanding - send one */
JMF 0:082731ede69f 138 init_timer(&timer);
JMF 0:082731ede69f 139
JMF 0:082731ede69f 140 countdown_ms(&timer, pClient->clientData.commandTimeoutMs);
JMF 0:082731ede69f 141 serialized_len = 0;
JMF 0:082731ede69f 142 rc = aws_iot_mqtt_internal_serialize_zero(pClient->clientData.writeBuf, pClient->clientData.writeBufSize,
JMF 0:082731ede69f 143 PINGREQ, &serialized_len);
JMF 0:082731ede69f 144 if(AWS_SUCCESS != rc) {
JMF 0:082731ede69f 145 FUNC_EXIT_RC(rc);
JMF 0:082731ede69f 146 }
JMF 0:082731ede69f 147
JMF 0:082731ede69f 148 /* send the ping packet */
JMF 0:082731ede69f 149 rc = aws_iot_mqtt_internal_send_packet(pClient, serialized_len, &timer);
JMF 0:082731ede69f 150 if(AWS_SUCCESS != rc) {
JMF 0:082731ede69f 151 //If sending a PING fails we can no longer determine if we are connected. In this case we decide we are disconnected and begin reconnection attempts
JMF 0:082731ede69f 152 //printf("JMF2\n");
JMF 0:082731ede69f 153 rc = _aws_iot_mqtt_handle_disconnect(pClient);
JMF 0:082731ede69f 154 FUNC_EXIT_RC(rc);
JMF 0:082731ede69f 155 }
JMF 0:082731ede69f 156
JMF 0:082731ede69f 157 pClient->clientStatus.isPingOutstanding = true;
JMF 0:082731ede69f 158 /* start a timer to wait for PINGRESP from server */
JMF 0:082731ede69f 159 countdown_sec(&pClient->pingTimer, pClient->clientData.keepAliveInterval);
JMF 0:082731ede69f 160
JMF 0:082731ede69f 161 FUNC_EXIT_RC(AWS_SUCCESS);
JMF 0:082731ede69f 162 }
JMF 0:082731ede69f 163
JMF 0:082731ede69f 164 /**
JMF 0:082731ede69f 165 * @brief Yield to the MQTT client
JMF 0:082731ede69f 166 *
JMF 0:082731ede69f 167 * Called to yield the current thread to the underlying MQTT client. This time is used by
JMF 0:082731ede69f 168 * the MQTT client to manage PING requests to monitor the health of the TCP connection as
JMF 0:082731ede69f 169 * well as periodically check the socket receive buffer for subscribe messages. Yield()
JMF 0:082731ede69f 170 * must be called at a rate faster than the keepalive interval. It must also be called
JMF 0:082731ede69f 171 * at a rate faster than the incoming message rate as this is the only way the client receives
JMF 0:082731ede69f 172 * processing time to manage incoming messages.
JMF 0:082731ede69f 173 * This is the internal function which is called by the yield API to perform the operation.
JMF 0:082731ede69f 174 * Not meant to be called directly as it doesn't do validations or client state changes
JMF 0:082731ede69f 175 *
JMF 0:082731ede69f 176 * @param pClient Reference to the IoT Client
JMF 0:082731ede69f 177 * @param timeout_ms Maximum number of milliseconds to pass thread execution to the client.
JMF 0:082731ede69f 178 *
JMF 0:082731ede69f 179 * @return An IoT Error Type defining successful/failed client processing.
JMF 0:082731ede69f 180 * If this call results in an error it is likely the MQTT connection has dropped.
JMF 0:082731ede69f 181 * iot_is_mqtt_connected can be called to confirm.
JMF 0:082731ede69f 182 */
JMF 0:082731ede69f 183 static IoT_Error_t _aws_iot_mqtt_internal_yield(AWS_IoT_Client *pClient, uint32_t timeout_ms) {
JMF 0:082731ede69f 184 IoT_Error_t yieldRc = AWS_SUCCESS;
JMF 0:082731ede69f 185
JMF 0:082731ede69f 186 uint8_t packet_type;
JMF 0:082731ede69f 187 ClientState clientState;
JMF 0:082731ede69f 188 awsTimer timer;
JMF 0:082731ede69f 189 init_timer(&timer);
JMF 0:082731ede69f 190 countdown_ms(&timer, timeout_ms);
JMF 0:082731ede69f 191 //printf("JMF: called internal_yeld\n");
JMF 0:082731ede69f 192 FUNC_ENTRY;
JMF 0:082731ede69f 193
JMF 0:082731ede69f 194 // evaluate timeout at the end of the loop to make sure the actual yield runs at least once
JMF 0:082731ede69f 195 do {
JMF 0:082731ede69f 196 clientState = aws_iot_mqtt_get_client_state(pClient);
JMF 0:082731ede69f 197 if(CLIENT_STATE_PENDING_RECONNECT == clientState) {
JMF 0:082731ede69f 198 //printf("JMF: pending_reconnect\n");
JMF 0:082731ede69f 199 if(AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL < pClient->clientData.currentReconnectWaitInterval) {
JMF 0:082731ede69f 200 yieldRc = NETWORK_RECONNECT_TIMED_OUT_ERROR;
JMF 0:082731ede69f 201 break;
JMF 0:082731ede69f 202 }
JMF 0:082731ede69f 203 //printf("JMF: do reconnect\n");
JMF 0:082731ede69f 204 yieldRc = _aws_iot_mqtt_handle_reconnect(pClient);
JMF 0:082731ede69f 205 /* Network reconnect attempted, check if yield timer expired before
JMF 0:082731ede69f 206 * doing anything else */
JMF 0:082731ede69f 207 continue;
JMF 0:082731ede69f 208 }
JMF 0:082731ede69f 209
JMF 0:082731ede69f 210 //printf("JMF: do internal_cycle_read \n");
JMF 0:082731ede69f 211 yieldRc = aws_iot_mqtt_internal_cycle_read(pClient, &timer, &packet_type);
JMF 0:082731ede69f 212 if(AWS_SUCCESS == yieldRc) {
JMF 0:082731ede69f 213 yieldRc = _aws_iot_mqtt_keep_alive(pClient);
JMF 0:082731ede69f 214 } else {
JMF 0:082731ede69f 215 // SSL read and write errors are terminal, connection must be closed and retried
JMF 0:082731ede69f 216 if(NETWORK_SSL_READ_ERROR == yieldRc || NETWORK_SSL_READ_TIMEOUT_ERROR == yieldRc
JMF 0:082731ede69f 217 || NETWORK_SSL_WRITE_ERROR == yieldRc || NETWORK_SSL_WRITE_TIMEOUT_ERROR == yieldRc) {
JMF 0:082731ede69f 218 //printf("JMF3 %d\n",yieldRc);
JMF 0:082731ede69f 219 yieldRc = _aws_iot_mqtt_handle_disconnect(pClient);
JMF 0:082731ede69f 220 }
JMF 0:082731ede69f 221 }
JMF 0:082731ede69f 222
JMF 0:082731ede69f 223 //printf("JMF: keepalive said: %d \n", yieldRc);
JMF 0:082731ede69f 224 if(NETWORK_DISCONNECTED_ERROR == yieldRc) {
JMF 0:082731ede69f 225 //printf("JMF: was a disconnect erro \n");
JMF 0:082731ede69f 226 pClient->clientData.counterNetworkDisconnected++;
JMF 0:082731ede69f 227 if(1 == pClient->clientStatus.isAutoReconnectEnabled) {
JMF 0:082731ede69f 228 yieldRc = aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_DISCONNECTED_ERROR,
JMF 0:082731ede69f 229 CLIENT_STATE_PENDING_RECONNECT);
JMF 0:082731ede69f 230 if(AWS_SUCCESS != yieldRc) {
JMF 0:082731ede69f 231 FUNC_EXIT_RC(yieldRc);
JMF 0:082731ede69f 232 }
JMF 0:082731ede69f 233
JMF 0:082731ede69f 234 pClient->clientData.currentReconnectWaitInterval = AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL;
JMF 0:082731ede69f 235 countdown_ms(&(pClient->reconnectDelayTimer), pClient->clientData.currentReconnectWaitInterval);
JMF 0:082731ede69f 236 /* Depending on timer values, it is possible that yield timer has expired
JMF 0:082731ede69f 237 * Set to rc to attempting reconnect to inform client that autoreconnect
JMF 0:082731ede69f 238 * attempt has started */
JMF 0:082731ede69f 239 yieldRc = NETWORK_ATTEMPTING_RECONNECT;
JMF 0:082731ede69f 240 } else {
JMF 0:082731ede69f 241 break;
JMF 0:082731ede69f 242 }
JMF 0:082731ede69f 243 } else if(AWS_SUCCESS != yieldRc) {
JMF 0:082731ede69f 244 break;
JMF 0:082731ede69f 245 }
JMF 0:082731ede69f 246 } while(!has_timer_expired(&timer));
JMF 0:082731ede69f 247 //printf("JMF: exit internal_yield with %d\n",yieldRc);
JMF 0:082731ede69f 248
JMF 0:082731ede69f 249 FUNC_EXIT_RC(yieldRc);
JMF 0:082731ede69f 250 }
JMF 0:082731ede69f 251
JMF 0:082731ede69f 252 /**
JMF 0:082731ede69f 253 * @brief Yield to the MQTT client
JMF 0:082731ede69f 254 *
JMF 0:082731ede69f 255 * Called to yield the current thread to the underlying MQTT client. This time is used by
JMF 0:082731ede69f 256 * the MQTT client to manage PING requests to monitor the health of the TCP connection as
JMF 0:082731ede69f 257 * well as periodically check the socket receive buffer for subscribe messages. Yield()
JMF 0:082731ede69f 258 * must be called at a rate faster than the keepalive interval. It must also be called
JMF 0:082731ede69f 259 * at a rate faster than the incoming message rate as this is the only way the client receives
JMF 0:082731ede69f 260 * processing time to manage incoming messages.
JMF 0:082731ede69f 261 * This is the outer function which does the validations and calls the internal yield above
JMF 0:082731ede69f 262 * to perform the actual operation. It is also responsible for client state changes
JMF 0:082731ede69f 263 *
JMF 0:082731ede69f 264 * @param pClient Reference to the IoT Client
JMF 0:082731ede69f 265 * @param timeout_ms Maximum number of milliseconds to pass thread execution to the client.
JMF 0:082731ede69f 266 *
JMF 0:082731ede69f 267 * @return An IoT Error Type defining successful/failed client processing.
JMF 0:082731ede69f 268 * If this call results in an error it is likely the MQTT connection has dropped.
JMF 0:082731ede69f 269 * iot_is_mqtt_connected can be called to confirm.
JMF 0:082731ede69f 270 */
JMF 0:082731ede69f 271 IoT_Error_t aws_iot_mqtt_yield(AWS_IoT_Client *pClient, uint32_t timeout_ms) {
JMF 0:082731ede69f 272 IoT_Error_t rc, yieldRc;
JMF 0:082731ede69f 273 ClientState clientState;
JMF 0:082731ede69f 274
JMF 0:082731ede69f 275 if(NULL == pClient || 0 == timeout_ms) {
JMF 0:082731ede69f 276 FUNC_EXIT_RC(NULL_VALUE_ERROR);
JMF 0:082731ede69f 277 }
JMF 0:082731ede69f 278
JMF 0:082731ede69f 279 clientState = aws_iot_mqtt_get_client_state(pClient);
JMF 0:082731ede69f 280 /* Check if network was manually disconnected */
JMF 0:082731ede69f 281 if(CLIENT_STATE_DISCONNECTED_MANUALLY == clientState) {
JMF 0:082731ede69f 282 FUNC_EXIT_RC(NETWORK_MANUALLY_DISCONNECTED);
JMF 0:082731ede69f 283 }
JMF 0:082731ede69f 284
JMF 0:082731ede69f 285 /* If we are in the pending reconnect state, skip other checks.
JMF 0:082731ede69f 286 * Pending reconnect state is only set when auto-reconnect is enabled */
JMF 0:082731ede69f 287 if(CLIENT_STATE_PENDING_RECONNECT != clientState) {
JMF 0:082731ede69f 288 /* Check if network is disconnected and auto-reconnect is not enabled */
JMF 0:082731ede69f 289 if(!aws_iot_mqtt_is_client_connected(pClient)) {
JMF 0:082731ede69f 290 //printf("JMF: %s:%d\n",__FILE__,__LINE__);
JMF 0:082731ede69f 291 FUNC_EXIT_RC(NETWORK_DISCONNECTED_ERROR);
JMF 0:082731ede69f 292 }
JMF 0:082731ede69f 293
JMF 0:082731ede69f 294 /* Check if client is idle, if not another operation is in progress and we should return */
JMF 0:082731ede69f 295 if(CLIENT_STATE_CONNECTED_IDLE != clientState) {
JMF 0:082731ede69f 296 FUNC_EXIT_RC(MQTT_CLIENT_NOT_IDLE_ERROR);
JMF 0:082731ede69f 297 }
JMF 0:082731ede69f 298
JMF 0:082731ede69f 299 rc = aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_CONNECTED_IDLE,
JMF 0:082731ede69f 300 CLIENT_STATE_CONNECTED_YIELD_IN_PROGRESS);
JMF 0:082731ede69f 301 if(AWS_SUCCESS != rc) {
JMF 0:082731ede69f 302 FUNC_EXIT_RC(rc);
JMF 0:082731ede69f 303 }
JMF 0:082731ede69f 304 }
JMF 0:082731ede69f 305
JMF 0:082731ede69f 306 yieldRc = _aws_iot_mqtt_internal_yield(pClient, timeout_ms);
JMF 0:082731ede69f 307
JMF 0:082731ede69f 308 if(NETWORK_DISCONNECTED_ERROR != yieldRc && NETWORK_ATTEMPTING_RECONNECT != yieldRc) {
JMF 0:082731ede69f 309 rc = aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_CONNECTED_YIELD_IN_PROGRESS,
JMF 0:082731ede69f 310 CLIENT_STATE_CONNECTED_IDLE);
JMF 0:082731ede69f 311 if(AWS_SUCCESS == yieldRc && AWS_SUCCESS != rc) {
JMF 0:082731ede69f 312 yieldRc = rc;
JMF 0:082731ede69f 313 }
JMF 0:082731ede69f 314 }
JMF 0:082731ede69f 315
JMF 0:082731ede69f 316 FUNC_EXIT_RC(yieldRc);
JMF 0:082731ede69f 317 }
JMF 0:082731ede69f 318
JMF 0:082731ede69f 319 #ifdef __cplusplus
JMF 0:082731ede69f 320 }
JMF 0:082731ede69f 321 #endif
JMF 0:082731ede69f 322