1 /*
2    This is a small demo of the NetX SMTP Client on the high-performance NetX TCP/IP stack.
3    This demo relies on Thread, NetX and SMTP Client API to perform simple SMTP mail
4    transfers in an SMTP client application to an SMTP mail server.
5  */
6 /* Note: This demo works for IPv4 only. */
7 
8 #include "nx_api.h"
9 #include "nx_ip.h"
10 #include "nxd_smtp_client.h"
11 
12 
13 #ifndef NX_DISABLE_IPV4
14 /* Define the host user name and mail box parameters */
15 #define USERNAME               "myusername"
16 #define PASSWORD               "mypassword"
17 #define FROM_ADDRESS           "my@mycompany.com"
18 #define RECIPIENT_ADDRESS      "your@yourcompany.com"
19 #define LOCAL_DOMAIN           "mycompany.com"
20 
21 #define SUBJECT_LINE           "NetX SMTP Client Demo"
22 #define MAIL_BODY              "NetX SMTP client is a simple SMTP client implementation  \r\n" \
23                                "that allow embedded devices to send email to an SMTP server. \r\n" \
24                                "This feature is intended to allow a device to send simple status\r\n " \
25                                "reports using the most universal Internet application, email.\r\n"
26 
27 
28 /* See the NetX SMTP Client User Guide for how to set the authentication type.
29    The most common authentication type is PLAIN. */
30 #define CLIENT_AUTHENTICATION_TYPE  NX_SMTP_CLIENT_AUTH_PLAIN
31 
32 
33 #define CLIENT_IP_ADDRESS  IP_ADDRESS(1,2,3,5)
34 #define SERVER_IP_ADDRESS  IP_ADDRESS(1,2,3,4)
35 #define SERVER_PORT        25
36 
37 
38 /* Define the NetX and ThreadX structures for the SMTP client appliciation. */
39 NX_PACKET_POOL                  ip_packet_pool;
40 NX_PACKET_POOL                  client_packet_pool;
41 NX_IP                           client_ip;
42 TX_THREAD                       demo_client_thread;
43 static NX_SMTP_CLIENT           demo_client;
44 
45 
46 void    _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
47 void    demo_client_thread_entry(ULONG info);
48 
49 /* Define main entry point.  */
main()50 int main()
51 {
52     /* Enter the ThreadX kernel.  */
53     tx_kernel_enter();
54 }
55 
56 /* Define what the initial system looks like.  */
tx_application_define(void * first_unused_memory)57 void    tx_application_define(void *first_unused_memory)
58 {
59 
60 UINT    status;
61 CHAR    *free_memory_pointer;
62 
63 
64     /* Setup the pointer to unallocated memory.  */
65     free_memory_pointer =  (CHAR *) first_unused_memory;
66 
67     /* Create IP default packet pool. This packets do not need a very large payload. */
68     status =  nx_packet_pool_create(&ip_packet_pool, "Default IP Packet Pool",
69                                     512, free_memory_pointer, 2048);
70 
71     /* Update pointer to unallocated (free) memory. */
72     free_memory_pointer = free_memory_pointer + 2048;
73 
74     /* Create SMTP Client packet pool. This is only for transmitting packets to the server.
75        It need not be a separate packet pool than the IP default packet pool but for more efficient
76        resource use, we use two different packet pools because the CLient SMTP messages
77        generally require more payload than IP control packets.
78 
79        Packet payload depends on the SMTP Client application requirements.  Size of packet payload
80        must include IP and TCP headers. For IPv6 connections, IP and TCP header data is 60 bytes. For IPv4
81        IP and TCP header data is 40 bytes (not including TCP options).
82     */
83 
84     status |=  nx_packet_pool_create(&client_packet_pool, "SMTP Client Packet Pool",
85                                      800, free_memory_pointer, (10*800));
86 
87     if (status != NX_SUCCESS)
88     {
89         return;
90     }
91 
92     /* Update pointer to unallocated (free) memory. */
93     free_memory_pointer = free_memory_pointer + (10*800);
94 
95     /* Initialize the NetX system. */
96     nx_system_initialize();
97 
98     /* Create the client thread */
99     status = tx_thread_create(&demo_client_thread, "client_thread",
100                               demo_client_thread_entry, 0, free_memory_pointer,
101                               2048, 16, 16,
102                               TX_NO_TIME_SLICE, TX_DONT_START);
103 
104     if (status != NX_SUCCESS)
105     {
106 
107         printf("Error creating Client thread. Status 0x%x\r\n", status);
108         return;
109     }
110 
111     /* Update pointer to unallocated (free) memory. */
112     free_memory_pointer =  free_memory_pointer + 4096;
113 
114 
115     /* Create Client IP instance. Remember to replace the generic driver
116        with a real ethernet driver to actually run this demo! */
117     status = nx_ip_create(&client_ip, "SMTP Client IP Instance", CLIENT_IP_ADDRESS, 0xFFFFFF00UL,
118                           &ip_packet_pool, _nx_ram_network_driver, free_memory_pointer,
119                           2048, 1);
120 
121     free_memory_pointer =  free_memory_pointer + 2048;
122 
123     /* Enable ARP and supply ARP cache memory. */
124     status =  nx_arp_enable(&client_ip, (void **) free_memory_pointer, 1040);
125 
126     /* Update pointer to unallocated (free) memory. */
127     free_memory_pointer = free_memory_pointer + 1040;
128 
129     /* Enable TCP for client. */
130     status =  nx_tcp_enable(&client_ip);
131 
132     if (status != NX_SUCCESS)
133     {
134         return;
135     }
136 
137     /* Enable ICMP for client. */
138     status =  nx_icmp_enable(&client_ip);
139 
140     if (status != NX_SUCCESS)
141     {
142         return;
143     }
144 
145     /* Start the client thread. */
146     tx_thread_resume(&demo_client_thread);
147 
148     return;
149 }
150 
151 
152 /* Define the smtp application thread task.   */
demo_client_thread_entry(ULONG info)153 void    demo_client_thread_entry(ULONG info)
154 {
155 
156 UINT        status;
157 UINT        error_counter = 0;
158 NXD_ADDRESS server_ip_address;
159 
160     NX_PARAMETER_NOT_USED(info);
161 
162     tx_thread_sleep(NX_IP_PERIODIC_RATE);
163 
164     /* Set up the server IP address. */
165     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
166     server_ip_address.nxd_ip_address.v4 = SERVER_IP_ADDRESS;
167 
168     /* The demo client username and password is the authentication
169        data used when the server attempts to authentication the client. */
170 
171     status =  nxd_smtp_client_create(&demo_client, &client_ip, &client_packet_pool,
172                                      USERNAME,
173                                      PASSWORD,
174                                      FROM_ADDRESS,
175                                      LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE,
176                                      &server_ip_address, SERVER_PORT);
177 
178     if (status != NX_SUCCESS)
179     {
180         printf("Error creating the client. Status: 0x%x.\n\r", status);
181         return;
182     }
183 
184     /* Create a mail instance with the above text message and recipient info. */
185     status =  nx_smtp_mail_send(&demo_client, RECIPIENT_ADDRESS, NX_SMTP_MAIL_PRIORITY_NORMAL,
186                                 SUBJECT_LINE, MAIL_BODY, sizeof(MAIL_BODY) - 1);
187 
188     /* Check for errors. */
189     if (status != NX_SUCCESS)
190     {
191 
192         /* Mail item was not sent. Note that we need not delete the client. The error status may be a failed
193            authentication check or a broken connection.  We can simply call nx_smtp_mail_send
194            again.  */
195 
196         error_counter++;
197     }
198 
199     /* Release resources used by client. Note that the transmit packet
200        pool must be deleted by the application if it no longer has use for it.*/
201     status = nx_smtp_client_delete(&demo_client);
202 
203     /* Check for errors. */
204     if (status != NX_SUCCESS)
205     {
206         error_counter++;
207     }
208 
209     return;
210 }
211 
212 #endif /* NX_DISABLE_IPV4 */
213