コード例 #1
0
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);

}
コード例 #2
0
/** 
 * 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;
}
コード例 #3
0
/** 
 * 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()*/
コード例 #4
0
ファイル: sirf_ext_aux.c プロジェクト: AxelLin/Drv
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 */
コード例 #5
0
ファイル: sirf_pal_os_mem_tlsf.c プロジェクト: AxelLin/Drv
/**
 * @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;   
}
コード例 #6
0
ファイル: sirf_ext_aux.c プロジェクト: AxelLin/Drv
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 */
コード例 #7
0
ファイル: sirf_pal_os_mem_tlsf.c プロジェクト: AxelLin/Drv
/**
 * @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;
}
コード例 #8
0
/** 
 * 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;
   }
}
コード例 #9
0
/** 
 * 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;
}
コード例 #10
0
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);
}
コード例 #11
0
/** 
 * 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;
}
コード例 #12
0
/** 
 * 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;

}
コード例 #13
0
/** 
 * 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() */
コード例 #14
0
/** 
 * 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;
}