tSIRF_RESULT SIRF_EXT_AUX_Open(tSIRF_UINT8 auxno, tSIRF_UINT32 port, tSIRF_UINT32 baud_rate) { tSIRF_RESULT tRet = SIRF_PAL_COM_ERROR; /* Unused parameter */ (tSIRF_VOID)auxno; /* no flow control for aux port */ c_ExtAuxPort = port; c_ExtAuxBaudRate = baud_rate; tRet = SIRF_PAL_OS_SEMAPHORE_Release( c_aux_open_sem ); return tRet; } /* SIRF_EXT_AUX_Open */
/** * 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() */
/** * Delete the AT command server instance and release all allocated resources * * @return Any error codes that occur during deletion, SIRF_SUCCESS otherwise */ tSIRF_RESULT SIRF_GPRS_AT_COMMAND_SERVER_Delete( tSIRF_VOID ) { tSIRF_RESULT result; tSIRF_RESULT ret_val = SIRF_SUCCESS; tSIRF_UINT32 handle; if (NULL == gprs_at_command.listener_mx) { return SIRF_GPRS_AT_COMMAND_SERVER_NOT_CREATED; } /* Just in case we were in data mode, which out. */ gprs_switch_from_data_mode(); /* Now shutdown the modem */ result = gprs_stop(gprs_at_command.uartno); if (SIRF_SUCCESS == ret_val) { ret_val = result; } /* Close port in case it is still open*/ for ( handle=0; handle < SIRF_GPRS_AT_COMMAND_MAX_HANDLES; handle++ ) { /* ignore the return code and close all handles */ (void)SIRF_GPRS_AT_COMMAND_SERVER_Close( (tSIRF_GPRS_HANDLE)handle ); } /* Close the thread */ gprs_at_command.thread_running = SIRF_FALSE; result = SIRF_PAL_OS_SEMAPHORE_Release(gprs_at_command.semaphore); if (SIRF_SUCCESS == ret_val) { ret_val = result; } result = SIRF_PAL_OS_THREAD_Delete(gprs_at_command.server_thread); if (SIRF_SUCCESS == ret_val) { ret_val = result; } /* Close the UART */ result = SIRF_EXT_UART_Close(gprs_at_command.uartno); if (SIRF_SUCCESS == ret_val) { ret_val = result; } result = SIRF_PAL_OS_MUTEX_Delete(gprs_at_command.queue_mx); if (SIRF_SUCCESS == ret_val) { ret_val = result; } /* Close the Mutex */ result = SIRF_PAL_OS_MUTEX_Delete( gprs_at_command.listener_mx ); if (SIRF_SUCCESS == ret_val) { ret_val = result; } /* Close the semaphore */ result = SIRF_PAL_OS_SEMAPHORE_Delete(gprs_at_command.semaphore); if (SIRF_SUCCESS == ret_val) { ret_val = result; } /* Set the initialization flag to NULL */ gprs_at_command.listener_mx = NULL; gprs_at_command.queue_mx = NULL; return result; } /* SIRF_GPRS_AT_COMMAND_Delete()*/
/** * Create the AT Command server instance * * @param port_name Name of the uart port the Modem is connected * * @return Success if the port was opened successfully */ tSIRF_RESULT SIRF_GPRS_AT_COMMAND_SERVER_Create( tSIRF_CHAR const * const port_name, tSIRF_CHAR const * const apn ) { tSIRF_RESULT result; tSIRF_MSG_SSB_EXT_UART_OPEN_PORT port_settings; /* This only works initially if gprs_at_command is in ZI data */ if (NULL != gprs_at_command.listener_mx) { return SIRF_GPRS_AT_COMMAND_SERVER_ALREADY_CREATED; } /* This is necessar if Create is ever called a second time */ memset( &gprs_at_command, 0, sizeof(gprs_at_command) ); /* Initialize the queues. These fucntion cannot fail */ fifo_queue_init( &gprs_at_command.msg_queue_gprs ); fifo_queue_init( &gprs_at_command.msg_queue_gprs_input ); gprs_at_command.command_timeout = DEFAULT_GPRS_RESPONSE_TIMEOUT; /* Open a uart port to the modem */ strlcpy(port_settings.port_name,port_name,sizeof(port_settings.port_name)); port_settings.baud_rate = SIRF_GPRS_AT_COMMAND_BAUD_RATE; port_settings.flow_control = SIRF_GPRS_AT_COMMAND_FLOW_CONTROL; /* Create the semaphore */ result = SIRF_PAL_OS_SEMAPHORE_Create(&gprs_at_command.semaphore,0); if ( SIRF_SUCCESS != result ) { return result; } result = SIRF_PAL_OS_MUTEX_Create( &gprs_at_command.listener_mx ); if ( SIRF_SUCCESS != result ) { goto GPRS_ERROR_1; } result = SIRF_PAL_OS_MUTEX_Create( &gprs_at_command.queue_mx ); if ( SIRF_SUCCESS != result ) { goto GPRS_ERROR_2; } gprs_at_command.msg_heap = Heap_Create( GprsMsgQueueHeap_notify, gprs_heap_space, sizeof(gprs_heap_space) ); if (NULL == gprs_at_command.msg_heap) { goto GPRS_ERROR_3; } /* Must open the UART last since it might call the callback fuctnion which * uses the heap and queues mutex's and semaphores, but before the * queue reading thread since the queue reading thread calls into the * uart */ result = SIRF_EXT_UART_Open(&gprs_at_command.uartno, &port_settings, SIRF_GPRS_AT_COMMAND_UartPacketCallbackATCommand, SIRF_PROTO_GPRS_AT_COMMAND_Parser); if ( SIRF_SUCCESS != result ) { goto GPRS_ERROR_4; } gprs_at_command.thread_running = SIRF_TRUE; result = SIRF_PAL_OS_THREAD_Create( SIRFLPL_THREAD_GPRS, (tSIRF_HANDLE)SIRF_GPRS_AT_COMMAND_ReadThread, &gprs_at_command.server_thread ); if (SIRF_SUCCESS != result) { goto GPRS_ERROR_5; } result = gprs_start(gprs_at_command.uartno, SIRF_GPRS_AT_COMMAND_FLOW_CONTROL, apn); if (SIRF_SUCCESS != result) { goto GPRS_ERROR_5; } return SIRF_SUCCESS; GPRS_ERROR_5: /* Must kill our own thread and delete it */ gprs_at_command.thread_running = SIRF_FALSE; (void)SIRF_PAL_OS_SEMAPHORE_Release(gprs_at_command.semaphore); (void)SIRF_PAL_OS_THREAD_Delete(gprs_at_command.server_thread); GPRS_ERROR_4: /* Heap_Create doesn't have a Heap Destroy */ GPRS_ERROR_3: (void)SIRF_PAL_OS_MUTEX_Delete(gprs_at_command.queue_mx); gprs_at_command.queue_mx = NULL; GPRS_ERROR_2: (void)SIRF_PAL_OS_MUTEX_Delete(gprs_at_command.listener_mx); gprs_at_command.listener_mx = NULL; GPRS_ERROR_1: (void)SIRF_PAL_OS_SEMAPHORE_Delete(gprs_at_command.semaphore); gprs_at_command.semaphore = NULL; return result; } /* SIRF_GPRS_AT_COMMAND_Create()*/