00001
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include <string.h>
00049
00050 #include "gpio.h"
00051
00052
00053
00054 #include "FreeRTOS.h"
00055 #include "task.h"
00056 #include "BasicSMTP.h"
00057 #include "semphr.h"
00058
00059
00060 #include "portmacro.h"
00061 #include "intc.h"
00062 #include "fsaccess.h"
00063 #include "conf_explorer.h"
00064 #include "config_file.h"
00065 #include "supervisor.h"
00066 #include "ethernet.h"
00067
00068
00069 #include "lwip/api.h"
00070 #include "lwip/tcpip.h"
00071 #include "lwip/memp.h"
00072 #include "lwip/stats.h"
00073 #include "lwip/opt.h"
00074 #include "lwip/api.h"
00075 #include "lwip/arch.h"
00076 #include "lwip/sys.h"
00077 #include "lwip/sockets.h"
00078 #include "netif/loopif.h"
00079
00080
00082 #define SMTP_ERRMSG_CONFIGURESMTP "SMTP has not been compiled, please set SMTP_USED to 1 at preprocessor level\r\n"
00083
00084
00085 #if (SMTP_USED == 1)
00086
00087
00088 #ifdef read
00089 #undef read
00090 #endif
00091
00092
00093 #ifdef write
00094 #undef write
00095 #endif
00096
00097
00099 #define SMTP_PORT 25
00101 #define SMTP_HELO_STRING "220"
00103 #define SMTP_END_OF_TRANSMISSION_STRING "221"
00105 #define SMTP_OK_STRING "250"
00107 #define SMTP_START_OF_TRANSMISSION_STRING "354"
00109 #define SMTP_DATA_STRING "DATA\r\n"
00111 #define SMTP_MAIL_END_STRING "\r\n.\r\n"
00113 #define SMTP_QUIT_STRING "QUIT\r\n"
00114
00116 #define SMTP_PACKET_SIZE 512
00118 #define SMTP_MAILS_QUEUE_SIZE 2
00119
00121 #define SMTP_CONFIG_FILE "A:/CFG/smtp.txt"
00122
00124 extern xSemaphoreHandle xCFGMutex;
00125
00127 typedef enum{
00128 eSMTPIdle = 0,
00129 eSMTPHeloSent,
00130 eSMTPMailFromSent,
00131 eSMTPMailToSent,
00132 eSMTPDataSent,
00133 eSMTPContentSent,
00134 eSMTPQuitSent,
00135 eSMTPMailSent,
00136 eSMTPNbState
00137 }eSMTPCurrentStateType;
00138
00139
00141 eSMTPCurrentStateType eSMTPCurrentState = eSMTPIdle;
00142
00144 portCHAR cTempBuffer[200];
00145
00147 portCHAR cMailTo[40];
00148
00150 portCHAR cMailFrom[40];
00151
00153 portCHAR cServerName[16];
00154
00156 static unsigned int uiSMTPPort;
00157
00159 static xQueueHandle xMailsQueue = 0;
00160
00162 typedef struct {
00163 portCHAR * File;
00164 portCHAR * Subject;
00165 Bool NeedFree;
00166 }xMailDef;
00167
00168
00169
00170
00171
00173 xMailDef xMailFromISR;
00174
00175
00182 void v_SMTP_Post(portCHAR * MailSubject, portCHAR * Filename)
00183 {
00184 xMailDef * pxMail;
00185
00186
00187 pxMail = (xMailDef *) pvPortMalloc(sizeof(xMailDef));
00188
00189 if (pxMail != NULL)
00190 {
00191
00192 pxMail->Subject = (portCHAR *) pvPortMalloc(strlen(MailSubject));
00193
00194 if (pxMail->Subject != NULL)
00195 {
00196
00197 strcpy(pxMail->Subject, MailSubject );
00198
00199 if (Filename != NULL)
00200 {
00201
00202 pxMail->File = (portCHAR *) pvPortMalloc(strlen(Filename));
00203
00204 if (pxMail->File != NULL)
00205 {
00206
00207 strcpy(pxMail->File, Filename );
00208 }
00209 }
00210 else
00211 {
00212
00213 pxMail->File = NULL;
00214 }
00215
00216 pxMail->NeedFree = pdTRUE;
00217
00218 xQueueSend( xMailsQueue, (void *)&pxMail, 0 );
00219 }
00220 }
00221 }
00222
00229 void v_SMTP_PostFromISR(portCHAR * MailSubject, portCHAR * Filename)
00230 {
00231 xMailDef * pxMail = &xMailFromISR;
00232 portBASE_TYPE xYieldRequired = pdFALSE;
00233
00234
00235 pxMail->Subject = MailSubject;
00236
00237 pxMail->File = Filename;
00238
00239 pxMail->NeedFree = pdFALSE;
00240
00241
00242 portENTER_CRITICAL();
00243 xQueueSendFromISR( xMailsQueue, (void *)&pxMail, &xYieldRequired );
00244 portEXIT_CRITICAL();
00245 }
00246
00247
00251 portTASK_FUNCTION( vBasicSMTPClient, pvParameters )
00252 {
00253
00254 struct sockaddr_in stServeurSockAddr;
00255 portLONG lRetval;
00256 portLONG lSocket = -1;
00257 portLONG ulResponseCode = 0;
00258 xMailDef * pxMail;
00259 int Size, SizeRead;
00260 portCHAR * pcRespData;
00261 int fd;
00262 portCHAR cToken[6];
00263
00264
00265 ( void ) pvParameters;
00266
00267
00268
00269 xMailsQueue = xQueueCreate( SMTP_MAILS_QUEUE_SIZE, sizeof( xMailDef * ) );
00270
00271
00272
00273 if( pdFALSE == x_supervisor_SemaphoreTake( xCFGMutex, 500 ) )
00274 {
00275
00276 uiSMTPPort = SMTP_PORT;
00277 cMailTo[0] = '\0';
00278 cMailFrom[0] = '\0';
00279 cServerName[0] = '\0';
00280 }
00281
00282 else
00283 {
00284
00285 if (config_file_get_value(SMTP_CONFIG_FILE, "port" , cToken) >= 0)
00286 {
00287 sscanf(cToken, "%u", &uiSMTPPort);
00288 }
00289
00290 else
00291 {
00292 uiSMTPPort = SMTP_PORT;
00293 }
00294
00295 if (config_file_get_value(SMTP_CONFIG_FILE, "mailto", cMailTo) < 0)
00296 {
00297 cMailTo[0] = '\0';
00298
00299 NAKED_TRACE_COM2("Warning : No mailto configured !!Please fill mailto= field in %s\r\n", SMTP_CONFIG_FILE);
00300 }
00301
00302 if (config_file_get_value(SMTP_CONFIG_FILE, "mailfrom", cMailFrom) < 0)
00303 {
00304 cMailFrom[0] = '\0';
00305
00306 NAKED_TRACE_COM2("Warning : No mailfrom configured !!Please fill mailfrom= field in %s\r\n", SMTP_CONFIG_FILE);
00307 }
00308
00309 if (config_file_get_value(SMTP_CONFIG_FILE, "server", cServerName) < 0)
00310 {
00311 cServerName[0] = '\0';
00312
00313 NAKED_TRACE_COM2("Warning : No server name configured !! Please fill server= field in %s\r\n", SMTP_CONFIG_FILE);
00314 }
00315
00316 x_supervisor_SemaphoreGive( xCFGMutex );
00317 }
00318
00319 for(;;)
00320 {
00321
00322
00323
00324 if( pdTRUE == xQueueReceive( xMailsQueue, &pxMail, ( portTickType )1000 ) )
00325 {
00326 if (cServerName[0] == '\0')
00327 {
00328
00329 NAKED_TRACE_COM2("Warning : No server name configured !! Please fill server= field in %s\r\n", SMTP_CONFIG_FILE);
00330 }
00331 else if (cMailTo[0] == '\0')
00332 {
00333
00334 NAKED_TRACE_COM2("Warning : No mailto configured !!Please fill mailto= field in %s\r\n", SMTP_CONFIG_FILE);
00335 }
00336 else if (cMailFrom[0] == '\0')
00337 {
00338
00339 NAKED_TRACE_COM2("Warning : No mailfrom configured !!Please fill mailfrom= field in %s\r\n", SMTP_CONFIG_FILE);
00340 }
00341 else
00342 {
00343
00344 memset(&stServeurSockAddr, 0, sizeof(stServeurSockAddr));
00345 stServeurSockAddr.sin_len = sizeof(stServeurSockAddr);
00346 stServeurSockAddr.sin_addr.s_addr = inet_addr(cServerName);
00347 stServeurSockAddr.sin_port = htons(uiSMTPPort);
00348 stServeurSockAddr.sin_family = AF_INET;
00349
00350
00351 if ( (lSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
00352 {
00353
00354 NAKED_TRACE_COM2("Socket Failed\r\n");
00355 }
00356
00357 if(connect(lSocket,(struct sockaddr *)&stServeurSockAddr,sizeof(stServeurSockAddr)) < 0)
00358 {
00359
00360 NAKED_TRACE_COM2("Connect Failed\r\n");
00361 }
00362 else
00363 {
00364 eSMTPCurrentState = eSMTPIdle;
00365 while ( eSMTPCurrentState != eSMTPMailSent )
00366 {
00367
00368 do
00369 {
00370 lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);
00371 }while (lRetval <= 0);
00372
00373 cTempBuffer[3] = '\0';
00374
00375 ulResponseCode = atoi(cTempBuffer);
00376
00377 switch (ulResponseCode)
00378 {
00379 case 220:
00380 {
00381
00382 send(lSocket, "HELO ", 5, 0);
00383 send(lSocket, cServerName, strlen(cServerName), 0);
00384 send(lSocket, "\r\n", 2, 0);
00385 eSMTPCurrentState = eSMTPHeloSent;
00386 break;
00387 }
00388 case 221:
00389 {
00390
00391 if (eSMTPCurrentState == eSMTPQuitSent)
00392 {
00393 eSMTPCurrentState = eSMTPMailSent;
00394 }
00395 break;
00396 }
00397 case 250:
00398 {
00399 if (eSMTPCurrentState == eSMTPHeloSent)
00400 {
00401
00402 send(lSocket, "MAIL FROM: <", 12, 0); ;
00403 send(lSocket, cMailFrom, strlen(cMailFrom), 0);
00404 send(lSocket, ">\r\n", 3, 0);
00405 eSMTPCurrentState = eSMTPMailFromSent;
00406 }
00407 else if (eSMTPCurrentState == eSMTPMailFromSent)
00408 {
00409
00410 send(lSocket, "RCPT TO: <", 10, 0); ;
00411 send(lSocket, cMailTo, strlen(cMailTo), 0);
00412 send(lSocket, ">\r\n", 3, 0);
00413 eSMTPCurrentState = eSMTPMailToSent;
00414 }
00415 else if (eSMTPCurrentState == eSMTPMailToSent)
00416 {
00417
00418 send(lSocket, SMTP_DATA_STRING, 6, 0);
00419 eSMTPCurrentState = eSMTPDataSent;
00420 }
00421 else if (eSMTPCurrentState == eSMTPContentSent)
00422 {
00423
00424 send(lSocket, SMTP_QUIT_STRING, 6, 0);
00425 eSMTPCurrentState = eSMTPQuitSent;
00426 }
00427 break;
00428 }
00429 case 354:
00430 {
00431 if (eSMTPCurrentState == eSMTPDataSent)
00432 {
00433
00434 send(lSocket, "Subject:", 8, 0);
00435
00436 send(lSocket, pxMail->Subject, strlen(pxMail->Subject), 0);
00437 send(lSocket, "\r\nFROM:", 7, 0);
00438 send(lSocket, cMailFrom, strlen(cMailFrom), 0);
00439 send(lSocket, "\r\nTO:", 5, 0);
00440 send(lSocket, cMailTo, strlen(cMailTo), 0);
00441 send(lSocket, "\r\n\r\n", 4, 0);
00442
00443 if (pxMail->File != NULL)
00444 {
00445
00446 pcRespData = (portCHAR *)pvPortMalloc(SMTP_PACKET_SIZE);
00447 if (pcRespData != NULL)
00448 {
00449 if ((fd = open((const char *)pxMail->File, O_RDONLY)) >= 0)
00450 {
00451 Size = fsaccess_file_get_size(fd);
00452
00453 while(Size > 0)
00454 {
00455
00456 SizeRead = read(fd, pcRespData, SMTP_PACKET_SIZE);
00457
00458 if (SizeRead <= 0)
00459 {
00460
00461 break;
00462 }
00463
00464 send(lSocket, pcRespData, SizeRead, 0);
00465
00466 Size -= SizeRead;
00467 }
00468
00469 close(fd);
00470
00471 vPortFree(pcRespData);
00472 }
00473 else
00474 {
00475
00476 NAKED_TRACE_COM2("Open file fails\r\n");
00477 }
00478 }
00479 else
00480 {
00481
00482 NAKED_TRACE_COM2("SMTP : Malloc fails\r\n");
00483 }
00484 }
00485
00486 send(lSocket, SMTP_MAIL_END_STRING, 5, 0);
00487 eSMTPCurrentState = eSMTPContentSent;
00488 }
00489 break;
00490 }
00491 default:
00492 {
00493
00494 NAKED_TRACE_COM2("Unimplented %l SMTP response from server\r\n",ulResponseCode);
00495
00496 eSMTPCurrentState = eSMTPMailSent;
00497 break;
00498 }
00499 }
00500 }
00501
00502 close(lSocket);
00503 }
00504
00505 if (pxMail->NeedFree == pdTRUE)
00506 {
00507
00508 if ( pxMail->File != NULL )
00509 {
00510
00511 vPortFree(pxMail->File);
00512 }
00513
00514 vPortFree(pxMail->Subject);
00515 vPortFree(pxMail);
00516 }
00517 }
00518 }
00519 }
00520 }
00521 #endif
00522
00523
00546 eExecStatus e_smtpclient_cmd_set_config( eModId xModId, signed short FsNavId,
00547 int ac, signed portCHAR *av[],
00548 signed portCHAR **ppcStringReply )
00549 {
00550 #if (SMTP_USED == 1)
00551 if (config_file_set_value(SMTP_CONFIG_FILE, ac, av) != 0)
00552 {
00553 *ppcStringReply = (signed portCHAR *)SHELL_ERRMSG_CONFIGERROR;
00554
00555 return( SHELL_EXECSTATUS_KO );
00556 }
00557
00558 if (!strcmp((char *)av[0] , "port"))
00559 {
00560 uiSMTPPort = atoi((char *)av[1]);
00561 *ppcStringReply = (signed portCHAR *)SHELL_MSG_CONFIG_SET;
00562 return( SHELL_EXECSTATUS_OK_NO_FREE );
00563 }
00564 else if (!strcmp((char *)av[0] , "mailto"))
00565 {
00566 cMailTo[0]='\0';
00567 strncat(cMailTo, (char *)av[1], Min(sizeof(cMailTo),strlen((char *)av[1])));
00568 *ppcStringReply = (signed portCHAR *)SHELL_MSG_CONFIG_SET;
00569 return( SHELL_EXECSTATUS_OK_NO_FREE );
00570 }
00571 else if (!strcmp((char *)av[0] , "mailfrom"))
00572 {
00573 cMailFrom[0]='\0';
00574 strncat(cMailFrom, (char *)av[1], Min(sizeof(cMailFrom),strlen((char *)av[1])));
00575 *ppcStringReply = (signed portCHAR *)SHELL_MSG_CONFIG_SET;
00576 return( SHELL_EXECSTATUS_OK_NO_FREE );
00577 }
00578 else if (!strcmp((char *)av[0] , "server"))
00579 {
00580 cServerName[0]='\0';
00581 strncat(cServerName, (char *)av[1], Min(sizeof(cServerName),strlen((char *)av[1])));
00582 *ppcStringReply = (signed portCHAR *)SHELL_MSG_CONFIG_SET;
00583 return( SHELL_EXECSTATUS_OK_NO_FREE );
00584 }
00585 else
00586 {
00587 *ppcStringReply = (signed portCHAR *)SHELL_ERRMSG_CONFIGERROR;
00588 return( SHELL_EXECSTATUS_KO );
00589 }
00590 #else
00591 *ppcStringReply = (signed portCHAR *)SMTP_ERRMSG_CONFIGURESMTP;
00592 return( SHELL_EXECSTATUS_KO );
00593 #endif
00594 }
00595
00596
00613 eExecStatus e_smtpclient_cmd_get_config( eModId xModId, signed short FsNavId,
00614 int ac, signed portCHAR *av[],
00615 signed portCHAR **ppcStringReply )
00616 {
00617
00618 if(ppcStringReply != NULL)
00619 {
00620
00621 *ppcStringReply = (signed portCHAR *)pvPortMalloc(MAX_CONFIG_FILE_SIZE);
00622 if( NULL == *ppcStringReply )
00623 {
00624 *ppcStringReply = (signed portCHAR *)SHELL_ERRMSG_MEMALLOC;
00625 return( SHELL_EXECSTATUS_KO );
00626 }
00627 #if (SMTP_USED == 1)
00628
00629 sprintf((char *)*ppcStringReply,"port=%u\r\nserver=%s\r\nmailto=%s\r\nmailfrom=%s\r\n",
00630 uiSMTPPort,
00631 cServerName,
00632 cMailTo,
00633 cMailFrom);
00634 #else
00635
00636 sprintf((char *)*ppcStringReply,"port=NotCompiled\r\nserver=NotCompiled\r\nmailto=NotCompiled\r\nmailfrom=NotCompiled\r\n");
00637 #endif
00638
00639 return( SHELL_EXECSTATUS_OK );
00640 }
00641 return( SHELL_EXECSTATUS_KO );
00642 }