Hardwired TCP/IP Chapter 11: W55MH32 SMTP Example
Hardwired TCP/IP Chapter 11: W55MH32 SMTP Example

Hardwired TCP/IP Chapter 11: W55MH32 SMTP Example
In this article, we will provide a detailed explanation on how to implement the SMTP protocol on the W55MH32 chip. Through practical examples, we will also teach you how to use the SMTP protocol to send emails to others on the W55MH32.
Other network protocols used in this example, such as DHCP and DNS, please refer to the relevant sections. Regarding the initialization process of the W55MH32, please refer to the Network Install section. We will not elaborate on it here.
1 Introduction to the SMTP Protocol
SMTP (Simple Mail Transfer Protocol) is a communication protocol used for email transmission. It is one of the Internet standard protocols, specifically designed for the sending and routing of emails. SMTP defines how emails are sent from the sender to the recipient's email server and specifies the email relay operations between servers.
2 Characteristics of the SMTP Protocol
For the text: The SMTP protocol uses plain text commands and responses (such as HELO, MAIL FROM, RCPT TO, etc.) for communication, and the email content is usually represented in ASCII code.
Request-response model: SMTP communication is based on the request-response model. The client sends a request, and the server returns a response according to the request.
Based on TCP: SMTP relies on the TCP protocol to provide reliable data transmission services. SMTP establishes a connection through TCP and sends emails.
Wide compatibility: SMTP is an international standard email transmission protocol, widely used in email systems, ensuring efficient communication between different systems.
Efficiency and reliability: The SMTP protocol is simple and easy to use, supporting error handling and retry mechanisms. When emails cannot be sent, they can be temporarily stored in a queue and retried to ensure reliable transmission.
Scalability: By extending the commands and response codes of the SMTP protocol, more email transmission features and functions can be supported.
Security: SMTP itself does not handle encryption, but it can combine SSL/TLS (SMTPS) to provide an encrypted channel, ensuring the security of email transmission.
Asynchronous transmission: SMTP supports asynchronous transmission, allowing email sending and receiving to occur at different times, improving efficiency and supporting batch processing.
Flexibility: SMTP is designed flexibly, allowing configuration of email routing, priority, size limits, etc., to meet different needs.
3 SMTP Application Scenarios
Next, let's take a look at what operations and applications can be accomplished using the SMTP protocol on the W55MH32?
- Remote monitoring of IoT devices: Utilize W55MH32 to achieve SMTP communication, collect sensor data, and send regular reports or alert emails.
- Environmental monitoring system: W55MH32 sends monitoring data (such as temperature, humidity, CO2 concentration, etc.) to the designated email via the SMTP protocol, ensuring timely information acquisition.
- Equipment status report and log recording: Trigger W55MH32 to automatically send equipment status reports or operation logs to the manager's email at regular intervals through scheduled tasks.
- Remote fault alarm and support: By combining sensors and the email sending function of W55MH32, automatic alarms can be achieved, reducing the need for manual intervention.
- Industrial automation and remote monitoring: Connect to the Internet using W55MH32 and use the SMTP protocol to send device status, alarms, etc. to the designated email.
- Remote control feedback: Receive emails through W55MH32, parse the email commands and perform corresponding operations, and then feedback the execution results to the sender via SMTP.
4 SMTP Email Sending Process
1. Connect to the SMTP server using the TCP protocol.
2. Send the handshake message.
3. Send the user authentication message.
4. Set the email sending address.
5. Transmit the email content.
6. Complete the email sending.
5 The main commands of the STMP protocol
Command | Function | Server Response |
HELO/EHLO | Identify the client’s identity. | 250: Success. |
MAIL FROM | Specify the sender’s email address. | 250: Email address accepted. |
RCPT TO | Specify recipient addresses (multiple allowed). | 250: Recipient accepted; |
DATA | Mark the start of email content. | 354: Ready to receive data; |
RSET | Reset the current session and clear all unfinished commands. | 250: Reset successfully. |
QUIT | Terminate the session. | 221: Connection closed. |
VRFY | Verify a username’s validity (often disabled due to security concerns). | 250: User exists; |
EXPN | List members of a mailing list (often disabled due to security concerns). | 250: Return mailing list members; |
HELP | Request help information. | Return help information. |
SMTP server response status code
Status Code | Category | Description |
211 | Success Status Code | System status or system help reply. |
214 | Success Status Code | Help information. |
220 | Success Status Code | Service ready. |
221 | Success Status Code | Service closing connection. |
250 | Success Status Code | Requested mail operation completed. |
251 | Success Status Code | Non-local user, but will forward. |
421 | Temporary Error Code | Service unavailable, closing transmission channel. |
450 | Temporary Error Code | Mailbox unavailable (e.g., mailbox locked). |
451 | Temporary Error Code | Request aborted (e.g., server error). |
452 | Temporary Error Code | System storage exceeded, unable to process command. |
500 | Permanent Error Code | Syntax error, command unrecognized. |
501 | Permanent Error Code | Syntax error in parameters. |
502 | Permanent Error Code | Command not implemented. |
503 | Permanent Error Code | Bad command sequence. |
504 | Permanent Error Code | Command parameter not implemented. |
550 | Permanent Error Code | Mailbox unavailable (e.g., user does not exist). |
551 | Permanent Error Code | User not local, try forwarding. |
552 | Permanent Error Code | Storage allocation exceeded. |
553 | Permanent Error Code | Illegal mailbox name. |
554 | Permanent Error Code | Transaction failed. |
6 The implementation process
Next, we implement the SMTP email sending function on the W55MH32.
Note: Since this example requires access to the Internet, please ensure that the configuration of the W55MH32 enables Internet access.
Step 1: SMTP Content Initialization
Sending Instruction Definition:
1. char hello[50] = "HELO localhost"; // Identity command
2. char hello_reply[] = "250 OK"; // Id successfully responded
3. char AUTH[50] = "AUTH LOGIN"; // Authentication request
4. char AUTH_reply[] = "334 dXNlcm5hbWU6"; // The authentication request was successfully sent
5. char name_126[100] = "wiznethk@126.com"; // 126 Login email address
6. char base64name_126[200]; // 126 base64 encoding of the login mailbox name
7. char name_reply[] = "334 UGFzc3dvcmQ6"; // The login name was sent successfully
8. char password_126[50] = "ZPURADLGRUPQLVBK"; // 126 Email login password
9. char base64password_126[100]; // base64 123 Password for logging in to the mailbox
10. char password_reply[] = "235 Authentication successful"; // Login successful response
11. char from[] = "wiznethk@126.com"; // Sender email
12. char from_reply[] = "250 Mail OK";
13. char to[] = "2510582273@qq.com"; // Recipient email address
14. char to_reply[] = "250 Mail OK";
15. char data_init[10] = "data"; // Request data transfer
16. char data_reply[] = "354"; // The request was successfully responded to HEAD
17. char Cc[] = ""; // Cc to email
18. char subject[] = "Hello!WIZnet!"; // subject
19. char content[] = "Hello!WIZnet!"; // text part
20. char mime_reply[] = "250 Mail OK queued as"; // The email was sent successfully
21. char mailfrom[50] = "MAIL FROM:<>";
22. char rcptto[50] = "rcpt to:<>";
23. char mime[200] = "From:\r\n";
24. char mime1[50] = "To:\r\n";
25. char mime2[50] = "Cc:\r\n";
26. char mime3[50] = "Subject:\r\n";
27. char mime4[50] = "MIME-Version:1.0\r\nContent-Type:text/plain\r\n\r\n";
28. char mime5[50] = "\r\n.\r\n";
Step 2: Initialize the email content:
1. mailmessage(); // Mail command information processing
The content of the mailmessage() function is as follows:
1. void mailmessage(void)
2. {
3. uint16_t len_from = strlen(from);
4. uint16_t len_to = strlen(to);
5. uint16_t len_Cc = strlen(Cc);
6. uint16_t len_sub = strlen(subject);
7. strcat(hello, "\r\n");
8. strcat(AUTH, "\r\n");
9. base64encode(name_126, base64name_126);
10. base64encode(password_126, base64password_126);
11. strcat(base64name_126, "\r\n");
12. strcat(base64password_126, "\r\n");
13. str_insert(mailfrom, from, 11);
14. strcat(mailfrom, "\r\n");
15. str_insert(rcptto, to, 9);
16. strcat(rcptto, "\r\n");
17. strcat(data_init, "\r\n");
18.
19. str_insert(mime, from, 5);
20. str_insert(mime1, to, 3);
21. str_insert(mime2, Cc, 3);
22. str_insert(mime3, subject, 8);
23. str_insert(mime5, content, 0);
24. strcat(mime, mime1);
25. strcat(mime, mime2);
26. strcat(mime, mime3);
27. strcat(mime, mime4);
28. strcat(mime, mime5);
29. }
Step 3: Use the DNS protocol to resolve the SMTP server address
1. if (do_dns(ethernet_buf, smtp_server_name, smtp_server_ip))
2. {
3. while (1)
4. {
5. }
6. }
Step 4: SMTP Email Sending Operation
1. while (1)
2. {
3. do_smtp(SOCKET_ID, ethernet_buf, smtp_server_ip); // smtp run
4. }
The content of the do_smtp() function is as follows:
1. void do_smtp(uint8_t sn, uint8_t *buf, uint8_t *smtp_server_ip)
2. {
3. volatile uint8_t ret;
4. uint32_t len = 0;
5. uint16_t anyport = 5000;
6. uint8_t Smtp_PORT = 25;
7. memset(buf, 0, ETHERNET_MAX_BUF_SIZE);
8. switch (getSn_SR(sn))
9. {
10. case SOCK_INIT:
11. ret = connect(sn, smtp_server_ip, Smtp_PORT);
12. break;
13. case SOCK_ESTABLISHED:
14. if (getSn_IR(sn) & Sn_IR_CON)
15. {
16. setSn_IR(sn, Sn_IR_CON);
17. }
18.
19. while (!Mail_Send_OK)
20. {
21. len = getSn_RX_RSR(sn);
22. if (len > 0)
23. {
24. memset(buf, 0, ETHERNET_MAX_BUF_SIZE);
25. len = recv(sn, (uint8_t *)buf, len);
26. send_mail(sn, buf, smtp_server_ip);
27. }
28. }
29. disconnect(sn);
30. break;
31. case SOCK_CLOSE_WAIT:
32. if ((len = getSn_RX_RSR(sn)) > 0)
33. {
34. while (!Mail_Send_OK)
35. {
36. len = recv(sn, (uint8_t *)buf, len);
37. send_mail(sn, buf, smtp_server_ip);
38. }
39. }
40. disconnect(sn);
41. break;
42. case SOCK_CLOSED:
43. socket(sn, Sn_MR_TCP, anyport++, 0x00);
44. break;
45. default:
46. break;
47. }
48. if (Mail_Send_OK)
49. {
50. while (1)
51. {
52. }
53. }
54. }
In this function, the program will execute a TCP Client mode state machine. For a detailed explanation, please refer to the TCP Client section. This will not be elaborated further here. When the program is in the SOCK_ESTABLISHED state (that is, successfully connected to the SMTP server), the SMTP server will actively send a message to W55MH32. After receiving this message, it will enter the send_mail() function to carry out the SMTP email sending process:
The content of the `send_mail()` function is as follows:
1. void send_mail(uint8_t sn, uint8_t *buf, uint8_t *smtp_server_ip)
2. {
3. volatile uint8_t ret;
4. switch (SMTP_STATE)
5. {
6. case waitfor220:
7. if (strstr((const char *)buf, "220") != NULL)
8. {
9. ret = send(sn, (uint8_t *)hello, strlen(hello));
10. SMTP_STATE = waitforHELO250;
11. }
12. else
13. {
14. printf("Connected failed!\r\n");
15. }
16. break;
17. case waitforHELO250:
18. if (strstr((const char *)buf, hello_reply) != NULL && strstr((const char *)buf, "Mail") == NULL)
19. {
20. ret = send(sn, (uint8_t *)AUTH, strlen(AUTH));
21. SMTP_STATE = waitforAUTH334;
22. }
23. else
24. {
25. printf("smtp handshake failed!\r\n");
26. }
27. break;
28. case waitforAUTH334:
29. if (strstr((const char *)buf, AUTH_reply) != NULL)
30. {
31. ret = send(sn, (uint8_t *)base64name_126, strlen(base64name_126));
32. SMTP_STATE = waitforuser334;
33. }
34. else
35. {
36. printf("AUTH authentication request failed!\r\n");
37. }
38. break;
39. case waitforuser334:
40. if (strstr((const char *)buf, name_reply) != NULL)
41. {
42. ret = send(sn, (uint8_t *)base64password_126, strlen(base64password_126));
43. SMTP_STATE = waitforpassword235;
44. }
45. else
46. {
47. printf("username send failed!\r\n");
48. }
49. break;
50. case waitforpassword235:
51. if (strstr((const char *)buf, password_reply) != NULL)
52. {
53. ret = send(sn, (uint8_t *)mailfrom, strlen(mailfrom));
54. SMTP_STATE = waitforsend250;
55. }
56. else
57. {
58. printf("password error!\r\n");
59. }
60. break;
61. case waitforsend250:
62. if (strstr((const char *)buf, from_reply) != NULL && strstr((const char *)buf, "queued as") == NULL)
63. {
64. ret = send(sn, (uint8_t *)rcptto, strlen(rcptto));
65. SMTP_STATE = waitforrcpt250;
66. }
67. else
68. {
69. printf("Send email failed to set up!\r\n");
70. }
71. break;
72. case waitforrcpt250:
73. if (strstr((const char *)buf, to_reply) != NULL)
74. {
75. ret = send(sn, (uint8_t *)data_init, strlen(data_init));
76. SMTP_STATE = waitfordate354;
77. }
78. else
79. {
80. printf("Failed to set the receiving mailbox!\r\n");
81. }
82. break;
83. case waitfordate354:
84. if (strstr((const char *)buf, data_reply) != NULL)
85. {
86. ret = send(sn, (uint8_t *)mime, strlen(mime));
87. SMTP_STATE = waitformime250;
88. }
89. else
90. {
91. printf("Failed to send content setup\r\n");
92. }
93. break;
94. case waitformime250:
95. if (strstr((const char *)buf, mime_reply) != NULL)
96. {
97. Mail_Send_OK = 1;
98. printf("mail send OK\r\n");
99. }
100. break;
101. default:
102. break;
103. }
104. }
In the `send_mail()` function, a mail sending state machine will be executed. The process is as shown in the following diagram:
1. SMTP Handshake: Send the HELO command, wait for the server to return the 250 OK response code, and confirm that the handshake is successful.
2. User Authentication:
(1) Request Authentication: Send the AUTH LOGIN command, indicating that the client needs authentication, and wait for the server to return 334, requesting the username.
(2) Submit Username: Send the username (e.g., base64name_126) after Base64 encoding, wait for the server to return 334, requesting the password.
(3) Submit Password: Send the password (e.g., base64password_126) after Base64 encoding, wait for the server to return 235, confirming the authentication success.
3. Set Email Sending Address:
(1) Set the Sender: Send MAIL FROM:<sender email>, wait for the server to return 250, confirming the successful setting of the sender address.
(2) Set the Recipient: Send RCPT TO:<recipient email>, wait for the server to return 250, confirming the successful setting of the recipient address.
4. Transmit Email Content:
(1) Request Data Transmission: Send the DATA command, indicating the start of transmitting email data, and wait for the server to return 354, indicating that it is ready to receive data.
(2) Send Email Data: Send the email data in the following format:
Sender Information: From:
Recipient Information: To:
Cc Information: Cc:
Email Subject: Subject:
Email Content: The actual text part The data ends with \r\n.\r\n
Wait for the server to return 250 to confirm that the email content has been successfully queued.
5. Complete email sending:
If the server returns 250, it indicates that the email has been sent successfully.
Set Mail_Send_OK = 1 and print the prompt message "Email sent successfully".
7 Run results
After the burning routine is executed, the first step is to perform PHY link detection, followed by obtaining network address information through DHCP, then resolving the SMTP server domain name through DNS, and finally sending emails, as shown in the following figure:
You can find the received emails in the settings for the email account you are using:
By using Wireshark for packet capture, the process is consistent with the send_mail() function.
8 Summary
This article explains how to implement the SMTP protocol on the W55MH32 chip. Through examples, it details the implementation process of using the SMTP protocol to send emails on this chip, including core steps such as initializing SMTP sending content, using the DNS protocol to resolve SMTP server addresses, and performing SMTP email sending operations. The article also analyzes the introduction, characteristics, application scenarios of the SMTP protocol, as well as its main commands and server response status codes, helping readers understand its practical application value in email transmission.
The next article will introduce the principle of NetBIOS and its application in network communication, and will also explain how to implement the NetBIOS function on the W55MH32 chip. Stay tuned!
WIZnet is a non-fabrication semiconductor company founded in 1998. Its products include the Internet processor iMCU™, which adopts TOE (TCP/IP Offloading Engine) technology and is based on a unique patented fully hardwired TCP/IP. iMCU™ is designed for embedded Internet devices in various applications.
WIZnet has over 70 distributors worldwide, with offices in Hong Kong, South Korea, and the United States, providing technical support and product marketing.
The region managed by the Hong Kong office includes: Australia, India, Turkey, and Asia (excluding South Korea and Japan).