]> git.sur5r.net Git - freertos/blob - Demo/lwIP_AVR32_UC3/NETWORK/BasicSMTP/BasicSMTP.c
Start to re-arrange files to include FreeRTOS+ in main download.
[freertos] / Demo / lwIP_AVR32_UC3 / NETWORK / BasicSMTP / BasicSMTP.c
1 /*This file has been prepared for Doxygen automatic documentation generation.*/\r
2 /*! \file *********************************************************************\r
3  *\r
4  * \brief Basic SMTP Client for AVR32 UC3.\r
5  *\r
6  * - Compiler:           GNU GCC for AVR32\r
7  * - Supported devices:  All AVR32 devices can be used.\r
8  * - AppNote:\r
9  *\r
10  * \author               Atmel Corporation: http://www.atmel.com \n\r
11  *                       Support and FAQ: http://support.atmel.no/\r
12  *\r
13  *****************************************************************************/\r
14 \r
15 /* Copyright (c) 2007, Atmel Corporation All rights reserved.\r
16  *\r
17  * Redistribution and use in source and binary forms, with or without\r
18  * modification, are permitted provided that the following conditions are met:\r
19  *\r
20  * 1. Redistributions of source code must retain the above copyright notice,\r
21  * this list of conditions and the following disclaimer.\r
22  *\r
23  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
24  * this list of conditions and the following disclaimer in the documentation\r
25  * and/or other materials provided with the distribution.\r
26  *\r
27  * 3. The name of ATMEL may not be used to endorse or promote products derived\r
28  * from this software without specific prior written permission.\r
29  *\r
30  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
31  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
32  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND\r
33  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,\r
34  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
35  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
36  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
37  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
39  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
40  */\r
41 \r
42 /*\r
43   Implements a simplistic SMTP client. First time the task is started, connection is made and\r
44   email is sent. Mail flag is then reset. Each time you press the Push Button 0, a new mail will be sent.\r
45 */\r
46 \r
47 #if (SMTP_USED == 1)\r
48 \r
49 #include <string.h>\r
50 \r
51 // Scheduler includes.\r
52 #include "FreeRTOS.h"\r
53 #include "task.h"\r
54 #include "BasicSMTP.h"\r
55 \r
56 \r
57 // Demo includes.\r
58 #include "portmacro.h"\r
59 #include "partest.h"\r
60 #include "intc.h"\r
61 #include "gpio.h"\r
62 \r
63 // lwIP includes.\r
64 #include "lwip/api.h"\r
65 #include "lwip/tcpip.h"\r
66 #include "lwip/memp.h"\r
67 #include "lwip/stats.h"\r
68 #include "lwip/opt.h"\r
69 #include "lwip/api.h"\r
70 #include "lwip/arch.h"\r
71 #include "lwip/sys.h"\r
72 #include "lwip/sockets.h"\r
73 #include "netif/loopif.h"\r
74 \r
75 //! SMTP default port\r
76 #define SMTP_PORT     25\r
77 //! SMTP EHLO code answer\r
78 #define SMTP_EHLO_STRING                  "220"\r
79 //! SMTP end of transmission code answer\r
80 #define SMTP_END_OF_TRANSMISSION_STRING   "221"\r
81 //! SMTP OK code answer\r
82 #define SMTP_OK_STRING                    "250"\r
83 //! SMTP start of transmission code answer\r
84 #define SMTP_START_OF_TRANSMISSION_STRING "354"\r
85 //! SMTP DATA<CRLF>\r
86 #define SMTP_DATA_STRING                  "DATA\r\n"\r
87 //! SMTP <CRLF>.<CRLF>\r
88 #define SMTP_MAIL_END_STRING              "\r\n.\r\n"\r
89 //! SMTP QUIT<CRLFCRLF>\r
90 #define SMTP_QUIT_STRING                  "QUIT\r\n"\r
91 \r
92 \r
93 //! Server address\r
94 #error configure SMTP server address\r
95 portCHAR cServer[] = "192.168.0.1";\r
96 \r
97 //! Fill here the mailfrom with your mail address\r
98 #error configure SMTP mail sender\r
99 char cMailfrom[] = "MAIL FROM: <sender@domain.com>\r\n";\r
100 \r
101 //! Fill here the mailto with your contact mail address\r
102 #error configure SMTP mail recipient\r
103 char cMailto[] = "RCPT TO: <recipient@domain.com>\r\n";\r
104 \r
105 //! Fill here the mailcontent with the mail you want to send\r
106 #error configure SMTP mail content\r
107 char cMailcontent[] ="Subject: *** SPAM ***\r\nFROM: \"Your Name here\" <sender@domain.com>\r\nTO: \"Your Contact here\" <recipient@domain.com>\r\n\r\nSay what you want here.";\r
108 \r
109 //! flag to send mail\r
110 Bool bSendMail = pdFALSE;\r
111 \r
112 //! buffer for SMTP response\r
113 portCHAR cTempBuffer[200];\r
114 \r
115 \r
116 //_____ D E C L A R A T I O N S ____________________________________________\r
117 //! interrupt handler.\r
118 #if __GNUC__\r
119 __attribute__((naked))\r
120 #elif __ICCAVR32__\r
121 #pragma shadow_registers = full   // Naked.\r
122 #endif\r
123 void vpushb_ISR( void );\r
124 \r
125 //! soft interrupt handler. where treatment should be done\r
126 #if __GNUC__\r
127 __attribute__((__noinline__))\r
128 #endif\r
129 static portBASE_TYPE prvpushb_ISR_NonNakedBehaviour( void );\r
130 \r
131 \r
132 \r
133 //! Basic SMTP client task definition\r
134 portTASK_FUNCTION( vBasicSMTPClient, pvParameters )\r
135 {\r
136   struct sockaddr_in stServeurSockAddr; \r
137   portLONG lRetval;\r
138   portLONG lSocket = -1;\r
139   \r
140   // configure push button 0 to produce IT on falling edge\r
141   gpio_enable_pin_interrupt(GPIO_PUSH_BUTTON_0 , GPIO_FALLING_EDGE);\r
142   // Disable all interrupts\r
143   vPortEnterCritical();\r
144   // register push button 0 handler on level 3\r
145   INTC_register_interrupt( (__int_handler)&vpushb_ISR, AVR32_GPIO_IRQ_0 + (GPIO_PUSH_BUTTON_0/8), INT3);\r
146   // Enable all interrupts\r
147   vPortExitCritical();  \r
148   \r
149   for (;;)\r
150   {\r
151     // wait for a signal to send a mail\r
152     while (bSendMail != pdTRUE)   vTaskDelay(200);\r
153 \r
154     // Disable all interrupts\r
155     vPortEnterCritical();\r
156     // clear the flag    \r
157     bSendMail = pdFALSE;\r
158     // Enable all interrupts\r
159     vPortExitCritical();    \r
160     // clear the LED\r
161     vParTestSetLED( 3 , pdFALSE );\r
162     // Set up port\r
163     memset(&stServeurSockAddr, 0, sizeof(stServeurSockAddr));\r
164     stServeurSockAddr.sin_len = sizeof(stServeurSockAddr);\r
165     stServeurSockAddr.sin_addr.s_addr = inet_addr(cServer);\r
166     stServeurSockAddr.sin_port = htons(SMTP_PORT);\r
167     stServeurSockAddr.sin_family = AF_INET;\r
168  \r
169     // socket as a stream\r
170     if ( (lSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)\r
171     {\r
172       // socket failed, blink a LED and stay here\r
173       for (;;) {\r
174         vParTestToggleLED( 4 );\r
175         vTaskDelay( 200 );\r
176       }\r
177     }\r
178     // connect to the server\r
179     if(connect(lSocket,(struct sockaddr *)&stServeurSockAddr, sizeof(stServeurSockAddr)) < 0)\r
180     {\r
181       // connect failed, blink a LED and stay here\r
182       for (;;) {\r
183         vParTestToggleLED( 6 );\r
184         vTaskDelay( 200 );\r
185       }\r
186     }\r
187     else\r
188     {\r
189 //Server: 220 SMTP Ready        \r
190       // wait for SMTP Server answer \r
191       do\r
192       {\r
193         lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);\r
194       }while (lRetval <= 0);        \r
195       if (strncmp(cTempBuffer, SMTP_EHLO_STRING, sizeof(cTempBuffer)) >= 0)\r
196       {\r
197 //Client: EHLO smtp.domain.com\r
198         // send ehlo\r
199         send(lSocket, "HELO ", 5, 0);\r
200         send(lSocket, cServer, strlen(cServer), 0);\r
201         send(lSocket, "\r\n", 2, 0);\r
202 //Server: 250 \r
203         // wait for SMTP Server answer\r
204         do\r
205         {\r
206           lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);\r
207         }while (lRetval <= 0);          \r
208         if (strncmp(cTempBuffer, SMTP_OK_STRING, sizeof(cTempBuffer)) >= 0)\r
209         {\r
210 //Client: MAIL FROM:<sender@domain.com>\r
211           // send MAIL FROM\r
212           send(lSocket, cMailfrom, strlen(cMailfrom), 0);            \r
213 //Server: 250 OK\r
214           // wait for SMTP Server answer\r
215           do\r
216           {\r
217             lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);\r
218           }while (lRetval <= 0);       \r
219           if (strncmp(cTempBuffer, SMTP_OK_STRING, sizeof(cTempBuffer)) >= 0)\r
220           {\r
221 //Client: RCPT TO:<receiver@domain.com>\r
222             // send RCPT TO\r
223             send(lSocket, cMailto, strlen(cMailto), 0);  \r
224 //Server: 250 OK\r
225             // wait for SMTP Server answer\r
226             do\r
227             {\r
228               lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);\r
229             }while (lRetval <= 0);\r
230             if (strncmp(cTempBuffer, SMTP_OK_STRING, sizeof(cTempBuffer)) >= 0)\r
231             {\r
232 //Client: DATA<CRLF>\r
233               // send DATA\r
234               send(lSocket, SMTP_DATA_STRING, 6, 0);  \r
235 //Server: 354 Start mail input; end with <CRLF>.<CRLF>              \r
236               // wait for SMTP Server answer\r
237               do\r
238               {\r
239                 lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);\r
240               }while (lRetval <= 0);\r
241               if (strncmp(cTempBuffer, SMTP_START_OF_TRANSMISSION_STRING, sizeof(cTempBuffer)) >= 0)\r
242               {\r
243                 // send content\r
244                 send(lSocket, cMailcontent, strlen(cMailcontent), 0);                 \r
245 //Client: <CRLF>.<CRLF>\r
246                 // send "<CRLF>.<CRLF>"\r
247                 send(lSocket, SMTP_MAIL_END_STRING, 5, 0);\r
248 //Server: 250 OK\r
249                 // wait for SMTP Server answer\r
250                 do\r
251                 {\r
252                   lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);\r
253                 }while (lRetval <= 0);\r
254                 if (strncmp(cTempBuffer, SMTP_OK_STRING, sizeof(cTempBuffer)) >= 0)\r
255                 {\r
256 //Client: QUIT<CRLFCRLF>\r
257                   // send QUIT \r
258                   send(lSocket, SMTP_QUIT_STRING, 8, 0);  \r
259 //Server: 221 smtp.domain.com closing transmission\r
260                   do\r
261                   {\r
262                     lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);\r
263                   }while (lRetval <= 0);                     \r
264                   if (strncmp(cTempBuffer, SMTP_END_OF_TRANSMISSION_STRING, sizeof(cTempBuffer)) >= 0)\r
265                   {\r
266                     vParTestSetLED( 3 , pdTRUE );\r
267                   }\r
268                 }\r
269               }\r
270             }             \r
271           }\r
272         }  \r
273         // close socket\r
274         close(lSocket);\r
275       }\r
276     }\r
277   }\r
278 }\r
279 \r
280 /*! \brief push button naked interrupt handler.\r
281  *\r
282  */\r
283 #if __GNUC__\r
284 __attribute__((naked))\r
285 #elif __ICCAVR32__\r
286 #pragma shadow_registers = full   // Naked.\r
287 #endif\r
288 void vpushb_ISR( void )\r
289 {\r
290  /* This ISR can cause a context switch, so the first statement must be a\r
291      call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any\r
292      variable declarations. */\r
293   portENTER_SWITCHING_ISR();\r
294 \r
295   prvpushb_ISR_NonNakedBehaviour();\r
296 \r
297   portEXIT_SWITCHING_ISR();\r
298 }\r
299 \r
300 /*! \brief push button interrupt handler. Here, declarations should be done\r
301  *\r
302  */\r
303 #if __GNUC__\r
304 __attribute__((__noinline__))\r
305 #elif __ICCAVR32__\r
306 #pragma optimize = no_inline\r
307 #endif\r
308 static portBASE_TYPE prvpushb_ISR_NonNakedBehaviour( void )\r
309 {\r
310   if (gpio_get_pin_interrupt_flag(GPIO_PUSH_BUTTON_0))\r
311   {\r
312     // set the flag    \r
313     bSendMail = pdTRUE;\r
314     // allow new interrupt : clear the IFR flag\r
315     gpio_clear_pin_interrupt_flag(GPIO_PUSH_BUTTON_0);\r
316   }\r
317   // no context switch required, task is polling the flag\r
318   return( pdFALSE );\r
319 }\r
320 \r
321 \r
322 \r
323 \r
324     \r
325 #endif\r