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