Wiznet makers

ronpang

Published August 06, 2025 © Apache License 2.0 (Apache-2.0)

130 UCC

63 WCC

32 VAR

0 Contests

1 Followers

0 Following

Hardwired TCP/IP Chapter 11: W55MH32 SMTP Example

Hardwired TCP/IP Chapter 11: W55MH32 SMTP Example

COMPONENTS
PROJECT DESCRIPTION

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.
HELO: For basic SMTP handshake.
EHLO: For extended SMTP (ESMTP).

250: Success.

MAIL FROM

Specify the sender’s email address.

250: Email address accepted.

RCPT TO

Specify recipient addresses (multiple allowed).

250: Recipient accepted;
550:User does not exist or refuses.

DATA

Mark the start of email content.
End with "." after sending the content.

354: Ready to receive data;
250:Message transmitted successfully.

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;
550: User does not exist.

EXPN

List members of a mailing list (often disabled due to security concerns).

250: Return mailing list members;
550: Refuse to provide the list.

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.

{FDA619A8-AC65-41FE-8450-E4D33EFEEB2C}

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).

Documents
Comments Write