示例#1
0
/*! \brief process an incoming connection
 *         parse the request and close/delete the connection
 *
 *  \note Input. The netconn to use to send and receive data.
 *
 */
portTASK_FUNCTION( prvweb_ProcessSingleConnection, pvParameters )
{
struct netconn * pxNewConnection;
portSHORT i;
portLONG err_count;
/*
  while( xSemaphoreTake(xMutexNbHTTPConn , portMAX_DELAY ) != pdTRUE );
  sCurrentNbHTTPConn++;
  // Release the mutex.
  xSemaphoreGive( xMutexNbHTTPConn );
*/

  pxNewConnection = ( struct netconn *)pvParameters;
  prvweb_ParseHTMLRequest( pxNewConnection );

  // Since we cannot know when the client has closed the connection(lwIP bug),
  // we set a 1000ms delay (the time for the file transfer to end), then we close
  // the connection ourselves.
  // NOTE FOR IMPROVMENTS: we could set this delay depending on the amount of
  // data that was sent to the client(the more the longer).
  vTaskDelay( 50 );
  err_count = 4;
  while( netconn_close( pxNewConnection ) != ERR_OK )
  {
    if (--err_count == 0) break;
    vTaskDelay( webSHORT_DELAY );
  }

  //vTaskDelay( 100 );
  err_count = 4;
  while( netconn_delete( pxNewConnection ) != ERR_OK )
  {
    if (--err_count == 0) break;
    vTaskDelay( webSHORT_DELAY );
  }
  // netconn_close( pxNewConnection );
  // netconn_delete( pxNewConnection );
  while( xSemaphoreTake(xMutexNbHTTPConn , portMAX_DELAY ) != pdTRUE );
  for (i = 0 ; i < webHTTP_NB_CONN ; i++)
  {
    if (tTaskHandle[i] == xTaskGetCurrentTaskHandle())
    {
      tTaskHandle[i] = NULL;
      break;
    }
  }
  sCurrentNbHTTPConn--;

  // Release the xWEBMutex if there are no other active connections.
  if( 0 == sCurrentNbHTTPConn )
  {
     x_supervisor_SemaphoreGive( xWEBMutex );
  }

  // Release the mutex.
  xSemaphoreGive( xMutexNbHTTPConn );

  vTaskDelete(NULL);
  /* nothing after delete task : this will not be reached */
}
示例#2
0
文件: pushb.c 项目: kerichsen/asf
/*!
 *  \brief Init the push button 3 sensor.
 *
 *  \return true upon success, false if error.
 */
bool b_pushb3_init ( void )
{
portCHAR token[6];

   // Get the xCFGMutex.
   if( pdTRUE == x_supervisor_SemaphoreTake( xCFGMutex, 20 ) )
   {
       // get the field
       if (config_file_get_value(SENSOR_PB3_CONFIG_FILE, "alarm" , token) >= 0)
       {
         // update value
         if (!strcmp(token, "on"))
         {
           bAlarm3 = pdTRUE;
         }
       }
     // Release the xCFGMutex.
     x_supervisor_SemaphoreGive( xCFGMutex );
   }
   /* configure push button to produce IT on input change */
   gpio_enable_pin_interrupt(PB3_POSITION , GPIO_PIN_CHANGE);
   /* Disable all interrupts */
   Disable_global_interrupt();
   /* register push button 3 handler on level 3 */
   INTC_register_interrupt( (__int_handler)&vpushb_ISR, AVR32_GPIO_IRQ_0 + (PB3_POSITION/8), AVR32_INTC_INT3);
   /* Enable all interrupts */
   Enable_global_interrupt();
   return (true);
}
示例#3
0
文件: datalog.c 项目: Mazetti/asf
/*!
 * \brief The log-to-file task.
 *
 */
static portTASK_FUNCTION( vLogToFileTask, pvParameters )
{
   int fd_current_logfile;


   /* Just to stop compiler warnings. */
   ( void ) pvParameters;

   xDataLogStatus = SYS_STATUS_RUNNING;

   /* Init the current log file name. */
   *acLogFileName = '\0';
   *acPreviousLogFileName = '\0';

   for(;;)
   {
      /* 1) Suspend ourselves. */
      vTaskSuspend( NULL ); // TO KEEP
      // NOTE: the task should be resumed when it is necessary to log the data
      // to the current log file, i.e.:
      //    (*) if the xLogQueue is 75% full,
      // OR
      //    (*) if the vDataLog_FlushLogs() has been called.

      // Take the data logger system mutex.
      if( false == x_supervisor_SemaphoreTake( xLOGMutex, 0 ) ) // 0 == Do not wait for the mutex.
      {
         // Pop the oldest logs from the logs queue so that the Control Panel
         // can still do logs acquisition.
         prv_vsave_logs( -1 );
         continue;
      }

      /* 2) Log the data into the current log file. */
      // 2a) Open the current log file.
      fd_current_logfile = prv_xopen_current_logfile();
      /* if( -1 == fd_current_logfile )
      {   // Should never happen (cf prv_xopen_current_logfile() final implem.)
         continue;
      } */
      // Although the open should not fail, if it happens(!!!), prv_vsave_logs()
      // will correctly handle the (-1) value by just poping the oldest logs from
      // the logs queue.

      // 2b) Move each item of the queue to the log file then close the file.
      prv_vsave_logs(fd_current_logfile);

      // Release the data logger system mutex.
      x_supervisor_SemaphoreGive( xLOGMutex );
   }
}
示例#4
0
//!
//! @brief USB Command Status Wrapper (CSW) management
//!
//! This function sends the status in relation with the last CBW.
//!
static void usb_mass_storage_csw(void)
{
  while (Is_usb_endpoint_stall_requested(EP_MS_IN))
  {
    if (Is_usb_setup_received()) usb_process_request();
  }

  while (Is_usb_endpoint_stall_requested(EP_MS_OUT))
  {
    if (Is_usb_setup_received()) usb_process_request();
  }

  // MSC Compliance - Free BAD out receive during SCSI command
  while( Is_usb_out_received(EP_MS_OUT) ) {
    Usb_ack_out_received_free(EP_MS_OUT);
  }

  while (!Is_usb_in_ready(EP_MS_IN));

  Usb_reset_endpoint_fifo_access(EP_MS_IN);

  //! Write CSW Signature
  Usb_write_endpoint_data(EP_MS_IN, 32, *(U32 *)&"USBS");

  //! Write stored CBW Tag
  Usb_write_endpoint_data(EP_MS_IN, 32, dCBWTag);

  //! Write data residual value
  Usb_write_endpoint_data(EP_MS_IN, 32,
                          usb_format_mcu_to_usb_data(32, g_scsi_data_remaining));

  //! Write command status
  Usb_write_endpoint_data(EP_MS_IN, 8, g_scsi_status);

  Usb_ack_in_ready_send(EP_MS_IN);

  // MSC Compliance - Wait end of all transmissions on USB line
  while( 0 != Usb_nb_busy_bank(EP_MS_IN) )
  {
    if (Is_usb_setup_received()) usb_process_request();
  }


  // Release the USB Mutex.
  if( true == xGiveUsbMutex )
  {
    x_supervisor_SemaphoreGive( xUSBMutex );
  }
}
示例#5
0
/*!
 *  \brief Init the temperature channel.
 *
 *  \return true upon success, false if error.
 */
bool b_temperature_init ( void )
{
portCHAR token[6];
portCHAR * unit;

   // Get the xCFGMutex.
   if( pdTRUE == x_supervisor_SemaphoreTake( xCFGMutex, 0 ) )
   {
       // get the field
       if (config_file_get_value(SENSOR_TEMP_CONFIG_FILE, "alarm" , token) >= 0)
       {
         // update value
         if (!strcmp(token, "on"))
         {
           b_temp_alarm = pdTRUE;
         }
       }
       if (config_file_get_value(SENSOR_TEMP_CONFIG_FILE, "min" , token) >= 0)
       {
         unit = strpbrk(token , "C");
         if (unit != NULL)
         {
           *unit = '\0';
         }
         l_temp_min = atol(token);
       }
       if (config_file_get_value(SENSOR_TEMP_CONFIG_FILE, "max" , token) >= 0)
       {
         unit = strpbrk(token , "C");
         if (unit != NULL)
         {
           *unit = '\0';
         }
         l_temp_max = atol(token);
       }
       if (config_file_get_value(SENSOR_TEMP_CONFIG_FILE, "lograte" , token) >= 0)
       {
         ul_temp_lograte = atoi(token);
       }
     // Release the xCFGMutex.
     x_supervisor_SemaphoreGive( xCFGMutex );
   }
   /* enable pin for sensor */
   gpio_enable_module_pin( ADC_TEMPERATURE_PIN , ADC_TEMPERATURE_FUNCTION );

   return (true);
}
示例#6
0
/*!
 *  \brief Init the potentiometer channel.
 *
 *  \return true upon success, false if error.
 */
bool b_potentiometer_init ( void )
{
portCHAR token[6];
portCHAR * percent;

   // Get the xCFGMutex.
   if( pdTRUE == x_supervisor_SemaphoreTake( xCFGMutex, 0 ) )
   {
       // get the field
       if (config_file_get_value(SENSOR_POT_CONFIG_FILE, "alarm" , token) >= 0)
       {
         // update value
         if (!strcmp(token, "on"))
         {
           b_pot_alarm = pdTRUE;
         }
       }
       if (config_file_get_value(SENSOR_POT_CONFIG_FILE, "min" , token) >= 0)
       {
         percent = strpbrk(token , "%");
         if (percent != NULL)
         {
           *percent = '\0';
         }
         sscanf(token, "%u", &ul_pot_min);
       }
       if (config_file_get_value(SENSOR_POT_CONFIG_FILE, "max" , token) >= 0)
       {
         percent = strpbrk(token , "%");
         if (percent != NULL)
         {
           *percent = '\0';
         }
         sscanf(token, "%u", &ul_pot_max);
       }
       if (config_file_get_value(SENSOR_POT_CONFIG_FILE, "lograte" , token) >= 0)
       {
         sscanf(token, "%u", &ul_pot_lograte);
       }
     // Release the xCFGMutex.
     x_supervisor_SemaphoreGive( xCFGMutex );
   }
   /* enable pin for sensor */
   gpio_enable_module_pin( ADC_POTENTIOMETER_PIN , ADC_POTENTIOMETER_FUNCTION );

   return (true);
}
示例#7
0
文件: joystick.c 项目: Mazetti/asf
/*!
 *  \brief Init the joystick sensor.
 *
 *  \return true upon success, false if error.
 */
bool b_joystick_init ( void )
{
portCHAR token[6];

   // Get the xCFGMutex.
   if( pdTRUE == x_supervisor_SemaphoreTake( xCFGMutex, 0 ) )
   {
       // get the field
       if (config_file_get_value(SENSOR_JS_CONFIG_FILE, "alarm" , token) >= 0)
       {
         // update value
         if (!strcmp(token, "on"))
         {
           bAlarm = pdTRUE;
         }
       }
     // Release the xCFGMutex.
     x_supervisor_SemaphoreGive( xCFGMutex );
   }
   /* configure joystick up to produce IT on all state change */
   gpio_enable_pin_interrupt(GPIO_JOYSTICK_UP , GPIO_PIN_CHANGE);
   /* configure joystick down to produce IT on all state change */
   gpio_enable_pin_interrupt(GPIO_JOYSTICK_DOWN , GPIO_PIN_CHANGE);
   /* configure joystick right to produce IT on all state change */
   gpio_enable_pin_interrupt(GPIO_JOYSTICK_RIGHT , GPIO_PIN_CHANGE);
   /* configure joystick left to produce IT on all state change */
   gpio_enable_pin_interrupt(GPIO_JOYSTICK_LEFT , GPIO_PIN_CHANGE);
   /* configure joystick press to produce IT on all state change */
   gpio_enable_pin_interrupt(GPIO_JOYSTICK_PUSH , GPIO_PIN_CHANGE);
   /* Disable all interrupts */
   Disable_global_interrupt();
   /* register joystick handler on level 3 */
   INTC_register_interrupt( (__int_handler)&vjoystick_ISR, AVR32_GPIO_IRQ_0 + (GPIO_JOYSTICK_UP/8), AVR32_INTC_INT3);
   INTC_register_interrupt( (__int_handler)&vjoystick_ISR, AVR32_GPIO_IRQ_0 + (GPIO_JOYSTICK_PUSH/8), AVR32_INTC_INT3);
   /* Enable all interrupts */
   Enable_global_interrupt();
   return (true);
}
示例#8
0
/*! \brief WEB server main task
 *         check for incoming connection and process it
 *
 */
portTASK_FUNCTION( vBasicWEBServer, pvParameters )
{
  struct netconn  *pxHTTPListener, *pxNewConnection;
  portCHAR        token[6];
  portSHORT       TaskIdx;
  portLONG        err_count;


  /* initialize current nb connection */
  sCurrentNbHTTPConn = 0;
  vSemaphoreCreateBinary( xMutexNbHTTPConn );

  x_default_page_len = strlen( pcDefaultPage );

  /* HTTP configuration. */
  // Get the xCFGMutex.
  if( pdFALSE == x_supervisor_SemaphoreTake( xCFGMutex, 0 ) )
  {
    // Failed to get the CFG mutex, use the default HTTP config.
    webHttpPort = webHTTP_PORT;
  }
  // Mutex has been taken
  else
  {
    // get the field value for port number
    if (config_file_get_value(HTTP_CONFIG_FILE, "port" , token) >= 0)
    {
      sscanf(token, "%u", &webHttpPort);
    }
    // if it does not exist, use the default value
    else
    {
      webHttpPort = webHTTP_PORT;
    }
    // Release the xCFGMutex.
    x_supervisor_SemaphoreGive( xCFGMutex );
  }

  // Create a new tcp connection handle
  pxHTTPListener = netconn_new( NETCONN_TCP );
  netconn_bind(pxHTTPListener, NULL, webHttpPort );
  netconn_listen( pxHTTPListener );
  // Loop forever
  for( ;; )
  {
#if ( (LWIP_VERSION) == ((1U << 24) | (3U << 16) | (2U << 8) | (LWIP_VERSION_RC)) )
    /* Wait for a first connection. */
    pxNewConnection = netconn_accept(pxHTTPListener);
#else
    while(netconn_accept(pxHTTPListener, &pxNewConnection) != ERR_OK)
    {
		vTaskDelay( webSHORT_DELAY );
	}
#endif
    if(pxNewConnection != NULL)
    {
      /* read the nb of connection, no need to use Mutex */
      while( webHTTP_NB_CONN == sCurrentNbHTTPConn )
      {
        vTaskDelay( webSHORT_DELAY );
      }

      // Take the xWEBMutex if there are no active connections.
      if( 0 == sCurrentNbHTTPConn )
      {
         if( pdFALSE == x_supervisor_SemaphoreTake( xWEBMutex, 0 ) )
         {
            prvweb_SendErrorPage( pxNewConnection, 503, "", "AVR32 UC3 Web server under maintenance." );
            // Close the connection.
            vTaskDelay( 50 );
            err_count = 4;
            while( netconn_close( pxNewConnection ) != ERR_OK )
            {
               if (--err_count == 0) break;
               vTaskDelay( webSHORT_DELAY );
            }
            err_count = 4;
            while( netconn_delete( pxNewConnection ) != ERR_OK )
            {
               if (--err_count == 0) break;
               vTaskDelay( webSHORT_DELAY );
            }
            continue;
         }
      }

      // Find an available spot in the tTaskHandle[] array.
      // We're sure to find one because sCurrentNbHTTPConn < webHTTP_NB_CONN.
      TaskIdx = 0;
      while( NULL != tTaskHandle[TaskIdx] ) TaskIdx++;

      while( xSemaphoreTake(xMutexNbHTTPConn , portMAX_DELAY ) != pdTRUE );
      sCurrentNbHTTPConn++;
      // Release the mutex.
      xSemaphoreGive( xMutexNbHTTPConn );

      // TRACE_COM2( "nb http conn:%d",sCurrentNbHTTPConn );

      if( xTaskCreate( prvweb_ProcessSingleConnection,
                                ( signed portCHAR * )"WCONN",
                                webHTTP_CONNECTION_STACK_SIZE, pxNewConnection,
                                webHTTP_CONNECTION_PRIORITY,
                                &tTaskHandle[TaskIdx] ) != pdPASS)
      {
          TRACE_COM2( "xTaskCreate() alloc error" );

          /* delete connection */
          err_count = 4;
          while( netconn_close( pxNewConnection ) != ERR_OK )
          {
            if (--err_count == 0) break;
            vTaskDelay( webSHORT_DELAY );
          }
          err_count = 4;
          while( netconn_delete( pxNewConnection ) != ERR_OK )
          {
            if (--err_count == 0) break;
            vTaskDelay( webSHORT_DELAY );
          }

          while( xSemaphoreTake(xMutexNbHTTPConn , portMAX_DELAY ) != pdTRUE );
          sCurrentNbHTTPConn--;
          // Release the xWEBMutex if there are no active connections.
          if( 0 == sCurrentNbHTTPConn )
          {
             x_supervisor_SemaphoreGive( xWEBMutex );
          }
          // Release the mutex.
          xSemaphoreGive( xMutexNbHTTPConn );
      }// end if task not created
    }// end if new connection

  }// end infinite loop
}
示例#9
0
/*!
 *  \brief a command line executor.
 *
 *  \param pcStringCmd    Input. The cmd line to execute. NULL-terminated string.
 *                        Format: cmd [arg] [arg=val], with 6 (arg,val) maximum.
 *                        WARNING: this string will be modified.
 *  \param xModId         Input. The module that is calling this exe function.
 *  \param FsNavId        Input. The file system navigator id to use if the cmd
 *                        is a file system command.
 *  \param ppcStringReply Output. The caller must free this string (by calling vportFree())
 *                        only if it is non-NULL and the returned status is OK.
 *
 *  \return the status of the command execution.
 */
eExecStatus Shell_exec( signed portCHAR *pcStringCmd,
                        eModId xModId,
                        signed short FsNavId,
                        signed portCHAR **ppcStringReply)
{
   eCmdStatus        xCmdStatus;
   portBASE_TYPE     ac;
   signed portCHAR   *av[SHELL_MAX_NBTOKEN];
   portBASE_TYPE     CmdIdx;
   int               i;
   eExecStatus       xRet;


   // 1) Identify the command and tokenize the rest of the command line.
   xCmdStatus = prvCmdIdentify_Tokenize( pcStringCmd, xModId, &ac, av, &CmdIdx );
   if(SHELL_CMDSTATUS_NOTFOUND == xCmdStatus)
   {   // Command not found.
      if(ppcStringReply != NULL)
      {
         *ppcStringReply = (signed portCHAR *)SHELL_MSG_CMDNOTFOUND;
      }
      return(SHELL_EXECSTATUS_KO);
   }
   else if(SHELL_CMDSTATUS_PERMISSIONDENIED == xCmdStatus)
   {   // Permission denied.
      if(ppcStringReply != NULL)
      {
         *ppcStringReply = (signed portCHAR *)SHELL_MSG_PERMISSIONDENIED;
      }
      return(SHELL_EXECSTATUS_KO);
   }

   /* Get the SHELLFS mutex for File system access. */
   // We put this check here to reduce the code footprint (normally it should be
   // in each fs cmd function).
   if( ( CmdIdx >= SHELL_FS_FIRSTCMDIDX ) && ( CmdIdx <= SHELL_FS_LASTCMDIDX ) )
   {
      if( pdFALSE == x_supervisor_SemaphoreTake( xSHELLFSMutex, 0 ) )
      {   // Failed to get the SHELLFS mutex.
         if(ppcStringReply != NULL)
         {
            *ppcStringReply = (signed portCHAR *)SHELL_ERRMSG_MAINTENANCEMODE;
         }
         return(SHELL_EXECSTATUS_KO);
      }
   }

   /* Special case for the !! command. Only for the SYS_MODID_COM1SHELL module,
      cf. a_cmd_registration[]. */
   if( 0 == CmdIdx ) // !! command
   {
      CmdIdx = PrevCmdIdx; // Execute the previous cmd.
      if( -1 == CmdIdx )
      {   // No previous command.
         if(ppcStringReply != NULL)
         {
            *ppcStringReply = (signed portCHAR *)SHELL_MSG_NOHISTORY;
         }
         return(SHELL_EXECSTATUS_KO);
      }
      ac = PrevCmdAc;      // NOTE: we take a shortcut here: we suppose the caller
                           // keeps the same pcStringCmd from one call to another.
      for(i=0; i<ac; i++)   av[i] = PrevCmdAv[i];
   }
   else
   {
      PrevCmdIdx = CmdIdx; // Save the cmd (used by the !! cmd).
      PrevCmdAc = ac;
      for(i=0; i<ac; i++)   PrevCmdAv[i] = av[i];
   }

   // 2) Execute the command.
   if(ppcStringReply != NULL)
      *ppcStringReply = NULL;
   xRet = a_cmd_registration[CmdIdx].pf_exec_cmd( xModId, FsNavId, ac, av, ppcStringReply );

   /* Release the SHELLFS mutex. */
   if( ( CmdIdx >= SHELL_FS_FIRSTCMDIDX ) && ( CmdIdx <= SHELL_FS_LASTCMDIDX ) )
   {
      x_supervisor_SemaphoreGive( xSHELLFSMutex );
   }

   return( xRet );
}
示例#10
0
文件: BasicSMTP.c 项目: Mazetti/asf
/*!
 *  \brief Task for SMTP management
 */
portTASK_FUNCTION( vBasicSMTPClient, pvParameters )
{

   struct sockaddr_in stServeurSockAddr;
   portLONG lRetval;
   portLONG lSocket = -1;
   portLONG ulResponseCode = 0;
   xMailDef * pxMail;
   int Size, SizeRead;
   portCHAR * pcRespData;
   int fd;
   portCHAR cToken[6];

   // Just to stop compiler warnings.
   ( void ) pvParameters;

   // Create the xMailsQueue capable of containing DATALOG_LOGSQUEUE_SIZE ptrs
   // to xLogDef structures.
   xMailsQueue = xQueueCreate( SMTP_MAILS_QUEUE_SIZE, sizeof( xMailDef * ) );

   // SMTP configuration.
   // Get the xCFGMutex.
   if( pdFALSE == x_supervisor_SemaphoreTake( xCFGMutex, 500 ) )
   {
      // Failed to get the CFG mutex, use the default HTTP config.
      uiSMTPPort = SMTP_PORT;
      cMailTo[0] = '\0';
      cMailFrom[0] = '\0';
      cServerName[0] = '\0';
   }
   // Mutex has been taken
   else
   {
      // get the field value for port number
      if (config_file_get_value(SMTP_CONFIG_FILE, "port" , cToken) >= 0)
      {
         sscanf(cToken, "%u", &uiSMTPPort);
      }
      // if it does not exist, use the default value
      else
      {
         uiSMTPPort = SMTP_PORT;
      }
      // try to get the mailto field
      if (config_file_get_value(SMTP_CONFIG_FILE, "mailto", cMailTo) < 0)
      {
         cMailTo[0] = '\0';
         // can't find field in config file, warn user
         NAKED_TRACE_COM2("Warning : No mailto configured !!Please fill mailto= field in %s\r\n", SMTP_CONFIG_FILE);
      }
      // try to get the mailfrom field
      if (config_file_get_value(SMTP_CONFIG_FILE, "mailfrom", cMailFrom) < 0)
      {
         cMailFrom[0] = '\0';
         // can't find field in config file, warn user
         NAKED_TRACE_COM2("Warning : No mailfrom configured !!Please fill mailfrom= field in %s\r\n", SMTP_CONFIG_FILE);
      }
      // try to get the server field
      if (config_file_get_value(SMTP_CONFIG_FILE, "server", cServerName) < 0)
      {
         cServerName[0] = '\0';
         // can't find field in config file, warn user
         NAKED_TRACE_COM2("Warning : No server name configured !! Please fill server= field in %s\r\n", SMTP_CONFIG_FILE);
      }
      // Release the xCFGMutex.
      x_supervisor_SemaphoreGive( xCFGMutex );
   }

   for(;;)
   {
      // NOTE: the task should be resumed when it is necessary to send a mail
      // Get the oldest mail from the queue.
      // NOTE: we are sure there is an item to get => no block time.
      if( pdTRUE == xQueueReceive( xMailsQueue, &pxMail, ( portTickType )1000 ) )
      {
         if (cServerName[0] == '\0')
         {
            // can't find field in config file, warn user
            NAKED_TRACE_COM2("Warning : No server name configured !! Please fill server= field in %s\r\n", SMTP_CONFIG_FILE);
         }
         else if (cMailTo[0] == '\0')
         {
            // can't find field in config file, warn user
            NAKED_TRACE_COM2("Warning : No mailto configured !!Please fill mailto= field in %s\r\n", SMTP_CONFIG_FILE);
         }
         else if (cMailFrom[0] == '\0')
         {
            // can't find field in config file, warn user
            NAKED_TRACE_COM2("Warning : No mailfrom configured !!Please fill mailfrom= field in %s\r\n", SMTP_CONFIG_FILE);
         }
         else
         {
            // Set up port
            memset(&stServeurSockAddr, 0, sizeof(stServeurSockAddr));
            stServeurSockAddr.sin_len = sizeof(stServeurSockAddr);
            stServeurSockAddr.sin_addr.s_addr = inet_addr(cServerName);
            stServeurSockAddr.sin_port = htons(uiSMTPPort);
            stServeurSockAddr.sin_family = AF_INET;

            // socket as a stream
            if ( (lSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
            {
               // socket failed
               NAKED_TRACE_COM2("Socket Failed\r\n");
            }
            // connect to the server
            if(connect(lSocket,(struct sockaddr *)&stServeurSockAddr,sizeof(stServeurSockAddr)) < 0)
            {
               // connect failed
               NAKED_TRACE_COM2("Connect Failed\r\n");
            }
            else
            {
               eSMTPCurrentState = eSMTPIdle;
               while ( eSMTPCurrentState != eSMTPMailSent )
               {
                  // wait for SMTP Server answer
                  do
                  {
                     lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);
                  }while (lRetval <= 0);

                  cTempBuffer[3] = '\0';
                  // Get the response code from server
                  ulResponseCode = atoi(cTempBuffer);

                  switch (ulResponseCode)
                  {
                     case 220:
                     {
                        // send helo
                        send(lSocket, "HELO ", 5, 0);
                        send(lSocket, cServerName, strlen(cServerName), 0);
                        send(lSocket, "\r\n", 2, 0);
                        eSMTPCurrentState = eSMTPHeloSent;
                        break;
                     }
                     case 221:
                     {
                        // QUIT sequence has been acknowledged by server
                        if (eSMTPCurrentState == eSMTPQuitSent)
                        {
                           eSMTPCurrentState = eSMTPMailSent;
                        }
                        break;
                     }
                     case 250:
                     {
                        if (eSMTPCurrentState == eSMTPHeloSent)
                        {
                           // send MAIL FROM
                           send(lSocket, "MAIL FROM: <", 12, 0); ;
                           send(lSocket, cMailFrom, strlen(cMailFrom), 0);
                           send(lSocket, ">\r\n", 3, 0);
                           eSMTPCurrentState = eSMTPMailFromSent;
                        }
                        else if (eSMTPCurrentState == eSMTPMailFromSent)
                        {
                           // send MAIL TO
                           send(lSocket, "RCPT TO: <", 10, 0); ;
                           send(lSocket, cMailTo, strlen(cMailTo), 0);
                           send(lSocket, ">\r\n", 3, 0);
                           eSMTPCurrentState = eSMTPMailToSent;
                        }
                        else if (eSMTPCurrentState == eSMTPMailToSent)
                        {
                           // send DATA
                           send(lSocket, SMTP_DATA_STRING, 6, 0);
                           eSMTPCurrentState = eSMTPDataSent;
                        }
                        else if (eSMTPCurrentState == eSMTPContentSent)
                        {
                           // send QUIT
                           send(lSocket, SMTP_QUIT_STRING, 6, 0);
                           eSMTPCurrentState = eSMTPQuitSent;
                        }
                        break;
                     }
                     case 354:
                     {
                        if (eSMTPCurrentState == eSMTPDataSent)
                        {
                           // set Subject field
                           send(lSocket, "Subject:", 8, 0);
                           // add subject
                           send(lSocket, pxMail->Subject, strlen(pxMail->Subject), 0);
                           send(lSocket, "\r\nFROM:", 7, 0);
                           send(lSocket, cMailFrom, strlen(cMailFrom), 0);
                           send(lSocket, "\r\nTO:", 5, 0);
                           send(lSocket, cMailTo, strlen(cMailTo), 0);
                           send(lSocket, "\r\n\r\n", 4, 0);
                           // if a file has been specified, copy the content in the mail body
                           if (pxMail->File != NULL)
                           {
                              // allocate response
                              pcRespData = (portCHAR *)pvPortMalloc(SMTP_PACKET_SIZE);
                              if (pcRespData != NULL)
                              {
                                 if ((fd = open((const char *)pxMail->File, O_RDONLY)) >= 0)
                                 {
                                    Size = fsaccess_file_get_size(fd);
                                    // get sectors of maximum size
                                    while(Size > 0)
                                    {
                                       // get the data from filesystem
                                       SizeRead = read(fd, pcRespData, SMTP_PACKET_SIZE);
                                       // if error occurs during the read
                                       if (SizeRead <= 0)
                                       {
                                          // end the loop and send what has already been added
                                          break;
                                       }
                                       // sned data to the socket
                                       send(lSocket, pcRespData, SizeRead, 0);
                                       // decrease remaing size
                                       Size -= SizeRead;
                                    }
                                    // close the file
                                    close(fd);
                                    // free the buffer
                                    vPortFree(pcRespData);
                                 }
                                 else
                                 {
                                    // warn user : can't open the file
                                    NAKED_TRACE_COM2("Open file fails\r\n");
                                 }
                              }
                              else
                              {
                                 // warn user : can't malloc the file buffer
                                 NAKED_TRACE_COM2("SMTP : Malloc fails\r\n");
                              }
                           }
                           // add "<CRLF>.<CRLF>"
                           send(lSocket, SMTP_MAIL_END_STRING, 5, 0);
                           eSMTPCurrentState = eSMTPContentSent;
                        }
                        break;
                     }
                     default:
                     {
                        // unknown SMTP code
                        NAKED_TRACE_COM2("Unimplented %l SMTP response from server\r\n",ulResponseCode);
                        // break loop and reset state machine
                        eSMTPCurrentState = eSMTPMailSent;
                        break;
                     }
                  }
               }
               // close the socket
               close(lSocket);
            }
            // if the item was not posted from ISR
            if (pxMail->NeedFree == pdTRUE)
            {
               // if a file has been specified
               if ( pxMail->File != NULL )
               {
                  // free the item
                  vPortFree(pxMail->File);
               }
               // free the items
               vPortFree(pxMail->Subject);
               vPortFree(pxMail);
            }
         }
      }
   }
}