1 /*
2    This is a small demo of POP3 Client on the high-performance NetX TCP/IP stack.
3    This demo relies on Thread, NetX and POP3 Client API to conduct
4    a POP3 mail session.
5  */
6 /* Note: This demo works for IPv4 only. */
7 
8 #include  "tx_api.h"
9 #include  "nx_api.h"
10 #ifndef NX_DISABLE_IPV4
11 #include  "nxd_pop3_client.h"
12 
13 #define DEMO_STACK_SIZE             4096
14 #define CLIENT_ADDRESS              IP_ADDRESS(192,2,2,61)
15 #define SERVER_ADDRESS              IP_ADDRESS(192,2,2,89)
16 #define SERVER_PORT                 110
17 
18 
19 /* Replace the 'ram' driver with your own Ethernet driver. */
20 void    _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
21 
22 /* Set up the POP3 Client.  */
23 
24 TX_THREAD           demo_client_thread;
25 NX_POP3_CLIENT      demo_client;
26 NX_PACKET_POOL      client_packet_pool;
27 NX_IP               client_ip;
28 
29 /* Use the maximum size payload to insure no packets are dropped. */
30 #define PAYLOAD_SIZE 1460
31 
32 /* Set up Client thread entry point. */
33 void    demo_thread_entry(ULONG info);
34 
35 
36   /* Shared secret is the same as password. */
37 
38 #define LOCALHOST                               "recipient@domain.com"
39 #define LOCALHOST_PASSWORD                      "testpwd"
40 
41 
42 /* Define main entry point.  */
main()43 int main()
44 {
45     /* Enter the ThreadX kernel.  */
46     tx_kernel_enter();
47 }
48 
49 
50 /* Define what the initial system looks like.  */
tx_application_define(void * first_unused_memory)51 void    tx_application_define(void *first_unused_memory)
52 {
53 
54 UINT     status;
55 UCHAR    *free_memory_pointer;
56 
57 
58     /* Setup the working pointer.  */
59     free_memory_pointer =  first_unused_memory;
60 
61     /* Create a client thread.  */
62     tx_thread_create(&demo_client_thread, "Client", demo_thread_entry, 0,
63                      free_memory_pointer, DEMO_STACK_SIZE, 1, 1,
64                      TX_NO_TIME_SLICE, TX_AUTO_START);
65 
66     free_memory_pointer =  free_memory_pointer + DEMO_STACK_SIZE;
67 
68     /* Initialize the NetX system.  */
69     nx_system_initialize();
70 
71     /* The demo client username and password is the authentication
72        data used when the server attempts to authentication the client. */
73 
74     /* Create Client packet pool. */
75     status =  nx_packet_pool_create(&client_packet_pool, "POP3 Client Packet Pool",
76                                     PAYLOAD_SIZE, free_memory_pointer, (PAYLOAD_SIZE * 10));
77     if (status != NX_SUCCESS)
78     {
79         return;
80     }
81 
82     /* Update pointer to unallocated (free) memory. */
83     free_memory_pointer = free_memory_pointer + (PAYLOAD_SIZE * 10);
84 
85 
86     /* Create IP instance for demo Client */
87     status = nx_ip_create(&client_ip, "POP3 Client IP Instance", CLIENT_ADDRESS, 0xFFFFFF00UL,
88                           &client_packet_pool, _nx_ram_network_driver, free_memory_pointer,
89                           2048, 1);
90 
91     if (status != NX_SUCCESS)
92     {
93         return;
94     }
95 
96     /* Update pointer to unallocated (free) memory. */
97     free_memory_pointer =  free_memory_pointer + 2048;
98 
99     /* Enable ARP and supply ARP cache memory. */
100     nx_arp_enable(&client_ip, (void *) free_memory_pointer, 1024);
101 
102     /* Update pointer to unallocated (free) memory. */
103     free_memory_pointer = free_memory_pointer + 1024;
104 
105     /* Enable TCP and ICMP for Client IP. */
106     nx_tcp_enable(&client_ip);
107     nx_icmp_enable(&client_ip);
108 
109     return;
110 }
111 
112 
113 
114 /* Define the application thread entry function. */
115 
demo_thread_entry(ULONG info)116 void    demo_thread_entry(ULONG info)
117 {
118 
119 UINT        status;
120 UINT        mail_item, number_mail_items;
121 UINT        bytes_downloaded = 0;
122 UINT        final_packet = NX_FALSE;
123 ULONG       total_size, mail_item_size, bytes_retrieved;
124 NX_PACKET   *packet_ptr;
125 
126     NX_PARAMETER_NOT_USED(info);
127 
128     /* Let the IP instance get initialized with driver parameters. */
129     tx_thread_sleep(NX_IP_PERIODIC_RATE);
130 
131 
132     /* Create a NetX POP3 Client instance with no byte or block memory pools.
133        Note that it uses its password for its APOP shared secret. */
134     status =  nx_pop3_client_create(&demo_client,
135                                     NX_TRUE /* if true, enables Client to send APOP command to authenticate */,
136                                     &client_ip, &client_packet_pool, SERVER_ADDRESS, SERVER_PORT,
137                                     LOCALHOST, LOCALHOST_PASSWORD);
138 
139     /* Check for error. */
140     if (status != NX_SUCCESS)
141     {
142 
143         status = nx_pop3_client_delete(&demo_client);
144 
145         /* Abort. */
146         return;
147     }
148 
149     /* Find out how many items are in our mailbox.  */
150     status = nx_pop3_client_mail_items_get(&demo_client, &number_mail_items, &total_size);
151 
152     printf("Got %d mail items, total size%ld \n", number_mail_items, total_size);
153 
154     /* If nothing in the mailbox, disconnect. */
155     if (number_mail_items == 0)
156     {
157 
158         nx_pop3_client_delete(&demo_client);
159 
160         return;
161     }
162 
163     /* Download all mail items.  */
164     mail_item = 1;
165 
166     while (mail_item <= number_mail_items)
167     {
168 
169         /* This submits a RETR request and gets the mail message size. */
170         status = nx_pop3_client_mail_item_get(&demo_client, mail_item, &mail_item_size);
171 
172         /* Loop to get the next mail message packet until the mail item is completely
173            downloaded. */
174         do
175         {
176 
177             status = nx_pop3_client_mail_item_message_get(&demo_client, &packet_ptr,
178                                                         &bytes_retrieved,
179                                                         &final_packet);
180 
181             if (status != NX_SUCCESS)
182             {
183 
184                 break;
185             }
186 
187             if (bytes_retrieved != 0)
188             {
189 
190                 printf("Received %ld bytes of data for item %d: %s\n", packet_ptr -> nx_packet_length, mail_item, packet_ptr -> nx_packet_prepend_ptr);
191             }
192 
193             nx_packet_release(packet_ptr);
194 
195             /* Determine if this is the last data packet. */
196             if (final_packet)
197             {
198                 /* It is. Let the server know it can delete this mail item. */
199                 status = nx_pop3_client_mail_item_delete(&demo_client, mail_item);
200 
201                 if (status != NX_SUCCESS)
202                 {
203 
204                     break;
205                 }
206             }
207 
208             /* Keep track of how much mail message data is left. */
209             bytes_downloaded += bytes_retrieved;
210 
211         } while (final_packet == NX_FALSE);
212 
213         /* Get the next mail item. */
214         mail_item++;
215 
216         tx_thread_sleep(NX_IP_PERIODIC_RATE);
217 
218     }
219 
220     /* Disconnect from the POP3 server. */
221     status = nx_pop3_client_quit(&demo_client);
222 
223     /* Delete the POP3 Client.  This will not delete the packet pool used by the POP3 Client to
224        transmit messages. */
225     status = nx_pop3_client_delete(&demo_client);
226 
227 }
228 #endif /* NX_DISABLE_IPV4  */
229