示例#1
0
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()*/