static tSIRF_VOID handle_response_timeout(tSIRF_VOID) { /* Send up a message to the listener that sent the command a timeout * error message */ tSIRF_MSG_GPRS_AT_COMMAND_SERVER_ERROR err; memset(&err,0,sizeof(err)); err.result = SIRF_GPRS_AT_COMMAND_SERVER_RESPONSE_TIMEOUT; err.data[0] = gprs_at_command.command_msg; err.data[1] = gprs_at_command.command_timeout; err.data[2] = gprs_at_command.command_responses; /* Ignore the return code when handling a different error case */ (void) SIRF_PAL_OS_MUTEX_Enter(gprs_at_command.listener_mx); /* Make sure the handle didn't get closed while waiting for the response */ if (gprs_at_command.listener[(tSIRF_UINT32)gprs_at_command.command_handle].msg_callback) { gprs_at_command.listener[(tSIRF_UINT32)gprs_at_command.command_handle].msg_callback( SIRF_MSG_GPRS_AT_COMMAND_SERVER_ERROR, &err, sizeof(err)); } /* Change the state to handle the next command */ gprs_at_command.state = GPRS_SERVER_STATE_AT_COMMAND; (void) SIRF_PAL_OS_MUTEX_Exit(gprs_at_command.listener_mx); }
/** * Handle a message to the GPRS modem * * @param msg The message to the GPRS modem * * @return SIRF_SUCCESS if successfully handled. */ tSIRF_RESULT handle_mas_input_msg(gprs_msg_t const * const msg, tSIRF_UINT32 * const timeout) { tSIRF_RESULT result; tSIRF_UINT8 packet[SIRF_PROTO_GPRS_AT_COMMAND_MAX_MSG_LENGTH]; tSIRF_UINT32 packet_length = sizeof(packet); tSIRF_UINT32 options = SIRF_CODEC_OPTIONS_GET_FIRST_MSG; /* handled a message */ *timeout = 0; /* we need to be in data mode. If the GPRS bearer is not open and the tcp connection is * not already established send back an error message */ if (GPRS_SERVER_STATE_TCP_IP_DATA == gprs_at_command.state) { result = SIRF_PROTO_MAS_Encode(msg->message_id, msg->message_structure, msg->message_length, packet, &packet_length, &options); if (SIRF_SUCCESS == result) { result = SIRF_EXT_UART_Send(gprs_at_command.uartno, packet, packet_length); } } else { /* +PWIPDATA message is going to fail, send error to client */ tSIRF_MSG_GPRS_AT_COMMAND_SERVER_ERROR err; tSIRF_UINT32 size; memset(&err,0,sizeof(err)); err.result = SIRF_GPRS_AT_COMMAND_SERVER_SEND_ERROR; err.data[0] = msg->message_id; err.data[1] = msg->message_length; size = SIRF_MSG_GPRS_AT_COMMAND_SERVER_ERROR_MAX_DATA_SIZE > msg->message_length ? msg->message_length : SIRF_MSG_GPRS_AT_COMMAND_SERVER_ERROR_MAX_DATA_SIZE; memcpy(&err.data[2],msg->message_structure,size); /* Ignore the return code when handling a different error case */ (void) SIRF_PAL_OS_MUTEX_Enter(gprs_at_command.listener_mx); if (gprs_at_command.listener[(tSIRF_UINT32)msg->handle].msg_callback) { gprs_at_command.listener[(tSIRF_UINT32)msg->handle].msg_callback( SIRF_MSG_GPRS_AT_COMMAND_SERVER_ERROR, &err, sizeof(err)); } (void) SIRF_PAL_OS_MUTEX_Exit(gprs_at_command.listener_mx); /* The error has been handled. Setting success here causes us to * not do an unexpected response handler */ result = SIRF_SUCCESS; } return result; }
/** * Close a previously opened handle * * @param handle The handle that was previously opened * * @return Any error code that occurs when freeing the handle */ tSIRF_RESULT SIRF_GPRS_AT_COMMAND_SERVER_Close( tSIRF_GPRS_HANDLE handle ) { tSIRF_RESULT result = SIRF_SUCCESS; if (NULL == gprs_at_command.listener_mx) { return SIRF_GPRS_AT_COMMAND_SERVER_NOT_CREATED; } if ( ((tSIRF_UINT32)handle >= SIRF_GPRS_AT_COMMAND_MAX_HANDLES ) || (NULL == gprs_at_command.listener[(tSIRF_UINT32)handle].msg_callback )) { return SIRF_GPRS_AT_COMMAND_SERVER_INVALID_HANDLE; } /* While this may only take one instruction to complete it needs protection * because it is checked for NULL before being called. */ result = SIRF_PAL_OS_MUTEX_Enter(gprs_at_command.listener_mx); if (SIRF_SUCCESS != result) { return result; } gprs_at_command.listener[(tSIRF_UINT32)handle].msg_callback = NULL; result = SIRF_PAL_OS_MUTEX_Exit(gprs_at_command.listener_mx); return result; } /* GPRS_AT_COMMAND_Close()*/
tSIRF_RESULT SIRF_EXT_AUX_Send( tSIRF_UINT8 auxno, tSIRF_UINT32 message_id, tSIRF_VOID *message_structure, tSIRF_UINT32 message_length ) { tSIRF_UINT8 payload[SIRF_EXT_AUX_MAX_MESSAGE_LEN]; tSIRF_UINT8 packet[SIRF_EXT_AUX_MAX_MESSAGE_LEN+10]; tSIRF_UINT32 payload_length = sizeof(payload); tSIRF_UINT32 packet_length = sizeof(packet); tSIRF_RESULT tRet = SIRF_SUCCESS; /* Unused parameter */ (tSIRF_VOID)auxno; /* Call the generic encode function, but does not support AI3 */ tRet = SIRF_CODEC_Encode( message_id, message_structure, message_length, payload, &payload_length ); if ( tRet != SIRF_SUCCESS ) { return tRet; } /* Apply the protocol wrapper */ tRet = SIRF_PROTO_Wrapper( payload, payload_length, packet, &packet_length ); if ( tRet != SIRF_SUCCESS ) { return tRet; } /* Send the data */ if (SIRF_SUCCESS == SIRF_PAL_OS_MUTEX_Enter(c_AUX_COM_WRITE_Critical)) { tRet = SIRF_PAL_COM_Write(c_ExtAuxHandle, packet, packet_length); SIRF_PAL_OS_MUTEX_Exit(c_AUX_COM_WRITE_Critical); } return tRet; } /* SIRF_EXT_AUX_Send */
/** * @brief TLSF based PAL allocation function * * @param size Amount of memory to allocate * * @return Memory address if successful, NULL otherwise. */ void *SIRF_PAL_OS_MEM_Alloc(tSIRF_UINT32 size) { void *ret; if (SIRF_FALSE == s_mem_initialized) { return NULL; } (void)SIRF_PAL_OS_MUTEX_Enter(s_MemoryMutex); ret = Heap_Malloc(s_MemoryHeap, size); (void)SIRF_PAL_OS_MUTEX_Exit(s_MemoryMutex); return ret; }
tSIRF_RESULT SIRF_EXT_AUX_Send_Passthrough( tSIRF_UINT8 auxno, tSIRF_VOID *PktBuffer, tSIRF_UINT32 PktLen ) { tSIRF_RESULT tRet = SIRF_SUCCESS; /* Unused parameter */ (tSIRF_VOID)auxno; if (SIRF_SUCCESS == SIRF_PAL_OS_MUTEX_Enter(c_AUX_COM_WRITE_Critical)) { tRet = SIRF_PAL_COM_Write(c_ExtAuxHandle, (tSIRF_UINT8*)PktBuffer, PktLen); SIRF_PAL_OS_MUTEX_Exit(c_AUX_COM_WRITE_Critical); } return tRet; } /* SIRF_EXT_AUX_Send_Passthrough */
/** * @brief TLSP based PAL free function * * @param pMem Memory block to free * * @return SIRF_SUCCESS if successful, SIRF_FAILURE otherwise */ tSIRF_RESULT SIRF_PAL_OS_MEM_Free(void *pMem) { tSIRF_RESULT result = SIRF_PAL_OS_ERROR; if (SIRF_TRUE == s_mem_initialized) { (void)SIRF_PAL_OS_MUTEX_Enter(s_MemoryMutex); Heap_Free(s_MemoryHeap, pMem); (void)SIRF_PAL_OS_MUTEX_Exit(s_MemoryMutex); result = SIRF_SUCCESS; } return result; }
/** * Get and initialize the next avaiable listern object. * * @param handle [out] Handle value of a found listener * @param callback [in] Function pointer to initialize the listener object * * @return SIRF_SUCCESS if a listener is allocated, and * SIRF_GPRS_AT_COMMAND_NO_MORE_HANDLES_AVAILABLE otherwise */ static tSIRF_RESULT GPRS_AT_COMMAND_SetNextAvailableListener( tSIRF_UINT32 * const handle, tSIRF_EXT_MSG_CALLBACK callback) { /* Assign default callback*/ tSIRF_UINT32 ii; tSIRF_RESULT result; result = SIRF_PAL_OS_MUTEX_Enter(gprs_at_command.listener_mx); if (SIRF_SUCCESS != result) { return result; } for ( ii=0; ii<SIRF_GPRS_AT_COMMAND_MAX_HANDLES; ii++ ) { if (NULL == gprs_at_command.listener[ii].msg_callback) { gprs_at_command.listener[ii].msg_callback = callback; fifo_queue_init( &gprs_at_command.listener[ii].msg_queue_mas ); fifo_queue_init( &gprs_at_command.listener[ii].msg_queue_mas_input ); gprs_at_command.listener[ii].data_index = 0xFFFFFFFF; *handle = ii; break; } } result = SIRF_PAL_OS_MUTEX_Exit(gprs_at_command.listener_mx); if (SIRF_SUCCESS != result) { return result; } if ( SIRF_GPRS_AT_COMMAND_MAX_HANDLES > ii ) { return SIRF_SUCCESS; } else { return SIRF_GPRS_AT_COMMAND_SERVER_NO_MORE_HANDLES_AVAILABLE; } }
/** * Process all the messages on one of the GPRS queues * * @param msg_queue Which message queue to process * @param handler Which handler function to use * @param timeout Pointer to amount of time to wait for the next message. * This is set to SIRF_TIMEOUT_INFINITE if there are no * messages left on the queue. * * @return result of the handler or SIRF_SUCCESS if there are no messages * process. */ static tSIRF_RESULT process_next_msg( fifo_queue_t * const msg_queue, tGPRS_MSG_HANDLER handler, tSIRF_UINT32 * const timeout) { gprs_msg_t *msg; fifo_link_t *link; tSIRF_RESULT result; UTIL_Assert(NULL != msg_queue); UTIL_Assert(NULL != handler); result = SIRF_PAL_OS_MUTEX_Enter(gprs_at_command.queue_mx); if(SIRF_SUCCESS != result) { return result; } /* Get the next message */ link = fifo_queue_remove_head( msg_queue ); result = SIRF_PAL_OS_MUTEX_Exit(gprs_at_command.queue_mx); if(SIRF_SUCCESS != result) { return result; } if (NULL != link) { msg = (gprs_msg_t*) link->data; result = handler(msg, timeout); Heap_Free(gprs_at_command.msg_heap,link); } else { /* No messages to process, we need to wait until one arrives */ *timeout = SIRF_TIMEOUT_INFINITE; } return result; }
static tSIRF_VOID handle_unexpected_result(tSIRF_UINT32 result) { tSIRF_UINT32 handle; /* Send up a message to the listener that sent the command a timeout * error message */ tSIRF_MSG_GPRS_AT_COMMAND_SERVER_ERROR err; memset(&err,0,sizeof(err)); err.result = result; /* Ignore the return code when handling a different error case */ (void) SIRF_PAL_OS_MUTEX_Enter(gprs_at_command.listener_mx); for (handle = 0; handle < SIRF_GPRS_AT_COMMAND_MAX_HANDLES; handle++) { if (gprs_at_command.listener[handle].msg_callback) { gprs_at_command.listener[handle].msg_callback( SIRF_MSG_GPRS_AT_COMMAND_SERVER_ERROR, &err, sizeof(err)); } } (void) SIRF_PAL_OS_MUTEX_Exit(gprs_at_command.listener_mx); }
/** * Packet callback called by the sirf_ext_uart when a full packet has arrived * * @param packet pointer to the packet * @param packet_length The length of the packet * * @return SIRF_SUCCESS if the packet was successfully processed, other error * code otherwise. */ static tSIRF_RESULT SIRF_GPRS_AT_COMMAND_UartPacketCallbackATCommand( tSIRF_UINT8 *packet, tSIRF_UINT32 packet_length ) { tSIRF_UINT32 message_id; tSIRF_UINT32 message_length; tSIRF_UINT32 options; tSIRF_RESULT result; fifo_link_t *link; gprs_msg_t *msg; options = SIRF_CODEC_OPTIONS_GET_FIRST_MSG; /* First message in the packet */ result = SIRF_PROTO_GPRS_AT_COMMAND_Decode(packet, packet_length, &message_id, NULL, /* return just the length */ &message_length, &options); if (SIRF_SUCCESS != result) { return result; } UTIL_Assert(0 != message_length); link = (fifo_link_t*) Heap_Malloc(gprs_at_command.msg_heap, sizeof(fifo_link_t) + sizeof(gprs_msg_t) + message_length); if (NULL == link) { return SIRF_GPRS_AT_COMMAND_SERVER_MEMORY_ERROR; } msg = (gprs_msg_t*)((tSIRF_UINT32)link + sizeof(fifo_link_t)); link->data = (void*)msg; msg->message_structure = (void*)((tSIRF_UINT32)msg + sizeof(gprs_msg_t)); /* actually decode the message */ result = SIRF_PROTO_GPRS_AT_COMMAND_Decode(packet, packet_length, &msg->message_id, msg->message_structure, &msg->message_length, &options); if (SIRF_SUCCESS != result) { return result; } /* Special case here that we have to switch protocols if the CONNECT message * comes in */ if (SIRF_MSG_GPRS_AT_COMMAND_CONNECT == msg->message_id) { SIRF_EXT_UART_SetCallbacksFromCallback(gprs_at_command.uartno, SIRF_GPRS_AT_COMMAND_UartPacketCallbackMAS, SIRF_PROTO_MAS_Parser); } result = SIRF_PAL_OS_MUTEX_Enter( gprs_at_command.queue_mx ); if (SIRF_SUCCESS != result) { return result; } fifo_queue_add_tail(&gprs_at_command.msg_queue_gprs, link); result = SIRF_PAL_OS_MUTEX_Exit( gprs_at_command.queue_mx ); if (SIRF_SUCCESS != result) { return result; } /* Signal a new message has arrived */ result = SIRF_PAL_OS_SEMAPHORE_Release( gprs_at_command.semaphore ); return result; }
/** * Callback to process MAS data packets * * @param packet Packet to process * @param packet_length Size of the packet * * @return SIRF_SUCCESS if successfully processed */ static tSIRF_RESULT SIRF_GPRS_AT_COMMAND_UartPacketCallbackMAS( tSIRF_UINT8* packet, tSIRF_UINT32 packet_length ) { tSIRF_UINT32 ii; tSIRF_UINT32 message_length; tSIRF_UINT32 message_id; fifo_link_t *link; gprs_msg_t *msg; tSIRF_RESULT result; tSIRF_UINT32 options; /* Search for the ETX character, and if found switch protocols immediately * so that no data is lost */ for (ii = 0; ii < packet_length; ii++) { if (SIRF_PROTO_MAS_ETX == packet[ii]) { /* make sure it wasn't escaped */ if (ii == 0 || SIRF_PROTO_MAS_DLE != packet[ii-1]) { SIRF_EXT_UART_SetCallbacksFromCallback(gprs_at_command.uartno, SIRF_GPRS_AT_COMMAND_UartPacketCallbackATCommand, SIRF_PROTO_GPRS_AT_COMMAND_Parser); /* Potential yet unlikely race condition here where we could be in the * middle of processing a MAS message (input or output) and ETX has come in. * This is OK and normal. Sending <pause> +++ <pause> while in AT command * mode will cause no harm since the modem is looking for AT<command><CR>. * We set the state here to try to reduce the likely hood of sending unnecessary * characeters. Also release the semaphore so the thread wakes up and * sets the timeout appropriately */ gprs_at_command.state = GPRS_SERVER_STATE_AT_COMMAND; SIRF_PAL_OS_SEMAPHORE_Release(gprs_at_command.semaphore); break; } } } /* Put the rest of the data on the queue. If there is none, just return */ if (0 == ii) { return SIRF_SUCCESS; } /* Find out how much memeory we need */ result = SIRF_PROTO_MAS_Decode(packet, ii, &message_id, NULL, &message_length, &options); link = (fifo_link_t*) Heap_Malloc(gprs_at_command.msg_heap, sizeof(fifo_link_t) + sizeof(gprs_msg_t) + message_length); if (NULL == link) { return SIRF_GPRS_AT_COMMAND_SERVER_MEMORY_ERROR; } msg = (gprs_msg_t*)((tSIRF_UINT32)link + sizeof(fifo_link_t)); link->data = (void*)msg; msg->message_structure = (void*)((tSIRF_UINT32)msg + sizeof(gprs_msg_t)); options = SIRF_CODEC_OPTIONS_GET_FIRST_MSG; /* First message in the packet */ /* actually decode the message */ result = SIRF_PROTO_MAS_Decode(packet, ii, &msg->message_id, msg->message_structure, &msg->message_length, &options); if (SIRF_SUCCESS != result) { return result; } msg->handle = gprs_at_command.data_handle; result = SIRF_PAL_OS_MUTEX_Enter( gprs_at_command.queue_mx ); if (SIRF_SUCCESS != result) { return result; } fifo_queue_add_tail(&gprs_at_command.listener[(tSIRF_UINT32)gprs_at_command.data_handle].msg_queue_mas, link); result = SIRF_PAL_OS_MUTEX_Exit( gprs_at_command.queue_mx ); if (SIRF_SUCCESS != result) { return result; } /* Signal a new message has arrived */ result = SIRF_PAL_OS_SEMAPHORE_Release( gprs_at_command.semaphore ); return result; }
/** * Send a message previously allocated * * @param msg The message to send. Must have been previously allocated by * MsgMalloc * * @return SIRF_SUCCESS if the message or specific error code. */ tSIRF_RESULT SIRF_GPRS_AT_COMMAND_SERVER_MsgSend( gprs_msg_t const * const msg) { tSIRF_RESULT result; fifo_link_t * link; UTIL_Assert(NULL != msg); link = (fifo_link_t*)((tSIRF_UINT32)msg - sizeof(fifo_link_t)); if ( ((tSIRF_UINT32)msg->handle >= SIRF_GPRS_AT_COMMAND_MAX_HANDLES ) || (NULL == gprs_at_command.listener[(tSIRF_UINT32)msg->handle].msg_callback )) { Heap_Free(gprs_at_command.msg_heap,link); return SIRF_GPRS_AT_COMMAND_SERVER_INVALID_HANDLE; } /* Check to see if we need to send a wipdata message, * Only do this if this is a MAS message and there isn't a data connection * already open for this handle */ if ((SIRF_LC_MAS == SIRF_GET_LC(msg->message_id)) && /* MAS Message. If we aren't in data mode send a message */ ((GPRS_SERVER_STATE_TCP_IP_DATA != gprs_at_command.state) || /* If we are in data mode, but opened via a differen handle, send wipdata */ ((GPRS_SERVER_STATE_TCP_IP_DATA == gprs_at_command.state) && (msg->handle != gprs_at_command.data_handle))) ) { gprs_at_command.data_handle = msg->handle; result = gprs_send_tcpip_wipdata(gprs_at_command.listener[(tSIRF_UINT32)msg->handle].data_index); if (SIRF_SUCCESS != result) { Heap_Free(gprs_at_command.msg_heap,link); return result; } } result = SIRF_PAL_OS_MUTEX_Enter( gprs_at_command.queue_mx ); if (SIRF_SUCCESS != result) { Heap_Free(gprs_at_command.msg_heap,link); return result; } /* Add it to the appripriate message queue */ if (SIRF_LC_MAS == SIRF_GET_LC(msg->message_id)) { fifo_queue_add_tail(&gprs_at_command.listener[(tSIRF_UINT32)msg->handle].msg_queue_mas_input, link); } else { fifo_queue_add_tail(&gprs_at_command.msg_queue_gprs_input, link); } result = SIRF_PAL_OS_MUTEX_Exit( gprs_at_command.queue_mx ); if (SIRF_SUCCESS != result) { return result; } /* Signal that a new message has arrived */ result = SIRF_PAL_OS_SEMAPHORE_Release( gprs_at_command.semaphore ); return result; } /* SIRF_GPRS_AT_COMMAND_Send() */
/** * Handle a message from the GPRS modem * * @param msg The message from the GPRS modem * * @return SIRF_SUCCESS if successfully handled. */ tSIRF_RESULT handle_gprs_msg(gprs_msg_t const * const msg, tSIRF_UINT32 * const timeout) { tSIRF_RESULT result; tSIRF_UINT32 ii; /* Timeout is 0 unless we handle a message that requires another response */ *timeout = 0; result = SIRF_PAL_OS_MUTEX_Enter( gprs_at_command.listener_mx ); if (SIRF_SUCCESS != result) { return result; } /* First handle unsolicited messages */ if (0 == gprs_at_command.command_msg){ for (ii = 0; ii < SIRF_GPRS_AT_COMMAND_MAX_HANDLES; ii++) { if (NULL != gprs_at_command.listener[ii].msg_callback) { (void)gprs_at_command.listener[ii].msg_callback( msg->message_id, msg->message_structure, msg->message_length); } } } else { gprs_server_state_t state; gprs_at_command.command_responses++; /* this was a solicited message: handle each message individually */ switch (gprs_at_command.command_msg) { case SIRF_MSG_GPRS_AT_COMMAND_PCGMI: { result = handle_response_SIRF_MSG_GPRS_AT_COMMAND_PCGMI( msg, gprs_at_command.command_responses, &state); } break; case SIRF_MSG_GPRS_AT_COMMAND_PWIPDATA: { result = handle_response_SIRF_MSG_GPRS_AT_COMMAND_PWIPDATA( msg, gprs_at_command.command_responses, &state); } break; case SIRF_MSG_GPRS_AT_COMMAND_PCCED: result = handle_response_SIRF_MSG_GPRS_AT_COMMAND_PCCED( msg, gprs_at_command.command_responses, gprs_at_command.command_data, &state); break; /* Single OK message expected for these ones */ case SIRF_MSG_GPRS_AT_COMMAND_PCMEE: case SIRF_MSG_GPRS_AT_COMMAND_PIFC: case SIRF_MSG_GPRS_AT_COMMAND_PWOPEN: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCFG_STOP_TCPIP: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCFG_START_TCPIP: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCFG_CONFIGURE_TCPIP: case SIRF_MSG_GPRS_AT_COMMAND_PWIPBR_CLOSE: case SIRF_MSG_GPRS_AT_COMMAND_PWIPBR_OPEN: case SIRF_MSG_GPRS_AT_COMMAND_PWIPBR_SET: case SIRF_MSG_GPRS_AT_COMMAND_PWIPBR_START: case SIRF_MSG_GPRS_AT_COMMAND_PWIPBR_STOP: case SIRF_MSG_GPRS_AT_COMMAND_PWIPBR_CFG_MANAGEMENT: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCREATE_UDP: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCREATE_TCP_CLIENT: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCREATE_TCP_SERVER: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCREATE_FTP: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCREATE_HTTP_CLIENT: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCREATE_SMTP_CLIENT: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCREATE_POP3_CLIENT: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCLOSE: result = handle_response_single_SIRF_MSG_GPRS_AT_COMMAND_OK_expected( msg, gprs_at_command.command_responses, &state); break; case SIRF_MSG_GPRS_AT_COMMAND_PCGMM: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCFG_TCPIP_VERSION: case SIRF_MSG_GPRS_AT_COMMAND_PWIPCFG_STORE_TCPIP_CFG: case SIRF_MSG_GPRS_AT_COMMAND_PWIPBR_GET: default: state = GPRS_SERVER_STATE_AT_COMMAND; result = SIRF_GPRS_AT_COMMAND_SERVER_COMMAND_NOT_SUPPORTED; }; if (NULL != gprs_at_command.listener[(tSIRF_UINT32)gprs_at_command.command_handle].msg_callback) { /* Pass the message up to the registered listener */ (void)gprs_at_command.listener[(tSIRF_UINT32)gprs_at_command.command_handle].msg_callback( msg->message_id, msg->message_structure, msg->message_length); } /* If the message is successfully handled then reset the state back * to ready to hanlde another command */ if (SIRF_GPRS_AT_COMMAND_SERVER_RESPONSE_FORWARD == result) { /* more responses expected for this message */ *timeout = gprs_at_command.command_timeout; } else { /* Reset the states in preperation for the next message */ gprs_at_command.state = state; gprs_at_command.command_handle = 0; gprs_at_command.command_msg = 0; gprs_at_command.command_responses = 0; } /* Special handling to transition to data mode if the state changes */ if (GPRS_SERVER_STATE_TCP_IP_DATA == gprs_at_command.state) { result = SIRF_EXT_UART_SetCallbacks( gprs_at_command.uartno, SIRF_GPRS_AT_COMMAND_UartPacketCallbackMAS, SIRF_PROTO_MAS_Parser); if (SIRF_SUCCESS != result) { gprs_at_command.state = GPRS_SERVER_STATE_AT_COMMAND; handle_unexpected_result(result); } } } result = SIRF_PAL_OS_MUTEX_Exit( gprs_at_command.listener_mx ); return result; }