1 /*This file has been prepared for Doxygen automatic documentation generation.*/
\r
2 /*! \file *********************************************************************
\r
4 * \brief Basic SMTP Client for AVR32 UC3.
\r
6 * - Compiler: GNU GCC for AVR32
\r
7 * - Supported devices: All AVR32 devices can be used.
\r
10 * \author Atmel Corporation: http://www.atmel.com \n
\r
11 * Support and FAQ: http://support.atmel.no/
\r
13 *****************************************************************************/
\r
15 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
\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
20 * 1. Redistributions of source code must retain the above copyright notice,
\r
21 * this list of conditions and the following disclaimer.
\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
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
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
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
47 #if (SMTP_USED == 1)
\r
51 // Scheduler includes.
\r
52 #include "FreeRTOS.h"
\r
54 #include "BasicSMTP.h"
\r
58 #include "portmacro.h"
\r
59 #include "partest.h"
\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
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
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
94 #error configure SMTP server address
\r
95 portCHAR cServer[] = "192.168.0.1";
\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
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
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
109 //! flag to send mail
\r
110 Bool bSendMail = pdFALSE;
\r
112 //! buffer for SMTP response
\r
113 portCHAR cTempBuffer[200];
\r
116 //_____ D E C L A R A T I O N S ____________________________________________
\r
117 //! interrupt handler.
\r
119 __attribute__((naked))
\r
121 #pragma shadow_registers = full // Naked.
\r
123 void vpushb_ISR( void );
\r
125 //! soft interrupt handler. where treatment should be done
\r
127 __attribute__((__noinline__))
\r
129 static portBASE_TYPE prvpushb_ISR_NonNakedBehaviour( void );
\r
133 //! Basic SMTP client task definition
\r
134 portTASK_FUNCTION( vBasicSMTPClient, pvParameters )
\r
136 struct sockaddr_in stServeurSockAddr;
\r
138 portLONG lSocket = -1;
\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
151 // wait for a signal to send a mail
\r
152 while (bSendMail != pdTRUE) vTaskDelay(200);
\r
154 // Disable all interrupts
\r
155 vPortEnterCritical();
\r
157 bSendMail = pdFALSE;
\r
158 // Enable all interrupts
\r
159 vPortExitCritical();
\r
161 vParTestSetLED( 3 , pdFALSE );
\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
169 // socket as a stream
\r
170 if ( (lSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
\r
172 // socket failed, blink a LED and stay here
\r
174 vParTestToggleLED( 4 );
\r
178 // connect to the server
\r
179 if(connect(lSocket,(struct sockaddr *)&stServeurSockAddr, sizeof(stServeurSockAddr)) < 0)
\r
181 // connect failed, blink a LED and stay here
\r
183 vParTestToggleLED( 6 );
\r
189 //Server: 220 SMTP Ready
\r
190 // wait for SMTP Server answer
\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
197 //Client: EHLO smtp.domain.com
\r
199 send(lSocket, "HELO ", 5, 0);
\r
200 send(lSocket, cServer, strlen(cServer), 0);
\r
201 send(lSocket, "\r\n", 2, 0);
\r
203 // wait for SMTP Server answer
\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
210 //Client: MAIL FROM:<sender@domain.com>
\r
212 send(lSocket, cMailfrom, strlen(cMailfrom), 0);
\r
214 // wait for SMTP Server answer
\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
221 //Client: RCPT TO:<receiver@domain.com>
\r
223 send(lSocket, cMailto, strlen(cMailto), 0);
\r
225 // wait for SMTP Server answer
\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
232 //Client: DATA<CRLF>
\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
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
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
249 // wait for SMTP Server answer
\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
256 //Client: QUIT<CRLFCRLF>
\r
258 send(lSocket, SMTP_QUIT_STRING, 8, 0);
\r
259 //Server: 221 smtp.domain.com closing transmission
\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
266 vParTestSetLED( 3 , pdTRUE );
\r
280 /*! \brief push button naked interrupt handler.
\r
284 __attribute__((naked))
\r
286 #pragma shadow_registers = full // Naked.
\r
288 void vpushb_ISR( void )
\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
295 prvpushb_ISR_NonNakedBehaviour();
\r
297 portEXIT_SWITCHING_ISR();
\r
300 /*! \brief push button interrupt handler. Here, declarations should be done
\r
304 __attribute__((__noinline__))
\r
306 #pragma optimize = no_inline
\r
308 static portBASE_TYPE prvpushb_ISR_NonNakedBehaviour( void )
\r
310 if (gpio_get_pin_interrupt_flag(GPIO_PUSH_BUTTON_0))
\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
317 // no context switch required, task is polling the flag
\r