PSoC 62S2 Wi-Fi BTパイオニアキットでのSMTPのメールクライアントを作成し、テスト用のSMTPサーバ「Smtp4dev」で動作確認します。。
テスト用のSMTPサーバ「Smtp4dev」のインストール
メール送信のテストのためにダミーのSMTPサーバ「Smtp4dev」を使用するため、「rnwood/smtp4dev」からWindows x64 binary standalone – Server edition「Rnwood.Smtp4dev-win-x64-3.2.0-ci20221023104.zip」をダウンロードします。
メールクライアントの作成
メールクライアント「Mail_Test」を作成します。「PSoC 62S2 Wi-Fi BTパイオニアキットを使ったTCP Client」で作成したTCP Clientをベースにして、メールクライアントの機能を追加します。
SMTP(Simple Mail Transfer Protocol)はメール送信に用いられるプロトコルで、TCPポートの 25番を用います。
- 128行目のcy_rslt_t tcp_client_recv_handler()で、テスト用のSMTPサーバ「Smtp4dev」からのデータを受信します。
- 155行目で受信データを表示します。TCP Clientを流用したために、このようなif文を使っています。
- 158行目でmail_send()を呼び出し、SMTPに従ってデータをテスト用のSMTPサーバ「Smtp4dev」に送信します。
- 11行目のcase文で、「HELO」を出力します。
- 26行目のcase文で、「MAIL FROM」を出力します。
- 42行目のcase文で、「RCPT TO」を出力します。
- 58行目のcase文で、「DATA」を出力します。
- 71行目のcase文で、メールヘッダと本文を出力し、メールの終了「.」を出力します。
- 103行目のcase文で、「QUIT」を出力して、SMTPを終了します。
source\tcp_client.c
・・・・ void mail_send(cy_socket_t mail_handle, int num) { // tomosoft cy_rslt_t result; char buf[MAX_TCP_DATA_PACKET_LENGTH]; //uint32_t bytes_received = 0; uint32_t bytes_sent = 0; switch (num) { case 0: memset(buf, 0, sizeof(buf)); /* HELOの送信 */ strcpy(buf, "HELO "); strcat(buf, "smtp4dev"); strcat(buf, "\n"); printf("send: %s", buf); result = cy_socket_send(mail_handle, buf, strlen(buf), CY_SOCKET_FLAGS_NONE, &bytes_sent); if (result == CY_RSLT_SUCCESS) { //printf("Acknowledgment sent to TCP server\n"); } break; case 1: memset(buf, 0, sizeof(buf)); /* MAIL FROMの送信 */ strcpy(buf, "MAIL FROM: "); strcat(buf, "<from@example.com>"); strcat(buf, "\r\n"); printf("send: %s", buf); result = cy_socket_send(mail_handle, buf, strlen(buf), CY_SOCKET_FLAGS_NONE, &bytes_sent); if (result == CY_RSLT_SUCCESS) { //printf("Acknowledgment sent to TCP server\n"); } break; case 2: memset(buf, 0, sizeof(buf)); /* RCPT TOの送信 */ strcpy(buf, "RCPT TO: "); strcat(buf, "<to@smtp4dev>"); strcat(buf, "\r\n"); printf("send: %s", buf); result = cy_socket_send(mail_handle, buf, strlen(buf), CY_SOCKET_FLAGS_NONE, &bytes_sent); if (result == CY_RSLT_SUCCESS) { //printf("Acknowledgment sent to TCP server\n"); } break; case 3: memset(buf, 0, sizeof(buf)); strcpy(buf, "DATA\r\n"); printf("send: %s", buf); result = cy_socket_send(mail_handle, buf, strlen(buf), CY_SOCKET_FLAGS_NONE, &bytes_sent); if (result == CY_RSLT_SUCCESS) { //printf("Acknowledgment sent to TCP server\n"); } break; case 4: memset(buf, 0, sizeof(buf)); strcpy(buf, "From:from@example.com"); strcat(buf, "\r\n"); strcat(buf, "To:to@smtp4dev"); strcat(buf, "\r\n"); strcat(buf, "Subject: テストメール"); strcat(buf, "\r\n"); strcat(buf, "\n"); strcat(buf, "これはテストメールです"); strcat(buf, "\r\n"); printf("send: %s", buf); result = cy_socket_send(mail_handle, buf, strlen(buf), CY_SOCKET_FLAGS_NONE, &bytes_sent); if (result == CY_RSLT_SUCCESS) { //printf("Acknowledgment sent to TCP server\n"); } memset(buf, 0, sizeof(buf)); strcpy(buf, ".\r\n"); result = cy_socket_send(mail_handle, buf, strlen(buf), CY_SOCKET_FLAGS_NONE, &bytes_sent); if (result == CY_RSLT_SUCCESS) { //printf("Acknowledgment sent to TCP server\n"); } printf("send: %s", buf); break; case 5: result = cy_socket_send(mail_handle, "QUIT\r\n", strlen("QUIT\r\n"), CY_SOCKET_FLAGS_NONE, &bytes_sent); if (result == CY_RSLT_SUCCESS) { //printf("Acknowledgment sent to TCP server\n"); } printf("send: QUIT\r\n"); break; } } /******************************************************************************* * Function Name: tcp_client_recv_handler ******************************************************************************* * Summary: * Callback function to handle incoming TCP server messages. * * Parameters: * cy_socket_t socket_handle: Connection handle for the TCP client socket * void *args : Parameter passed on to the function (unused) * * Return: * cy_result result: Result of the operation * *******************************************************************************/ cy_rslt_t tcp_client_recv_handler(cy_socket_t socket_handle, void *arg) { /* Variable to store number of bytes send to the TCP server. */ //uint32_t bytes_sent = 0; /* Variable to store number of bytes received. */ uint32_t bytes_received = 0; char message_buffer[MAX_TCP_DATA_PACKET_LENGTH]; cy_rslt_t result; // printf("============================================================\n"); memset(message_buffer, 0, sizeof(message_buffer)); result = cy_socket_recv(socket_handle, message_buffer, TCP_LED_CMD_LEN, CY_SOCKET_FLAGS_NONE, &bytes_received); if (message_buffer[0] == LED_ON_CMD) { /* Turn the LED ON. */ cyhal_gpio_write(CYBSP_USER_LED, CYBSP_LED_STATE_ON); printf("LED turned ON\n"); sprintf(message_buffer, ACK_LED_ON); } else if (message_buffer[0] == LED_OFF_CMD) { /* Turn the LED OFF. */ cyhal_gpio_write(CYBSP_USER_LED, CYBSP_LED_STATE_OFF); printf("LED turned OFF\n"); sprintf(message_buffer, ACK_LED_OFF); } else { printf("rcv %s", message_buffer); sprintf(message_buffer, MSG_INVALID_CMD); } mail_send(socket_handle, recv_count); recv_count++; if (recv_count >= 6) { recv_count = 0; } /* Send acknowledgment to the TCP server in receipt of the message received. result = cy_socket_send(socket_handle, message_buffer, strlen(message_buffer), CY_SOCKET_FLAGS_NONE, &bytes_sent); if (result == CY_RSLT_SUCCESS) { printf("Acknowledgment sent to TCP server\n"); } */ return result; } ・・・・
メールクライアントの実行
作成したメールクライアント「Mail_Test」を実行し、メールサーバ「Smtp4dev」を使用してメールを送信します。
- インストールしたメールサーバ「Smtp4dev」の「・・・Rnwood.Smtp4dev-win-x64-3.2.0-ci20221023104\Rnwood.Smtp4dev.exe」を実行します。
- TeraTermを起動すると、TeraTermには次のようにSMTPプロトコルの実行ログが表示されます。
- メールサーバ「Smtp4dev」のログが「http://localhost:5000」に表示されます。「Messages」タブには次のように表示されます。
- メールサーバ「Smtp4dev」のログが「http://localhost:5000」に表示されます。「Sessions」タブには次のように表示されます。