Files
esp-protocols/components/mbedtls_cxx/examples/tls_client/main/tls_client.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

153 lines
3.5 KiB
C++
Raw Normal View History

/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include "esp_log.h"
#include "mbedtls_wrap.hpp"
using namespace idf::mbedtls_cxx;
namespace {
constexpr auto *TAG = "simple_tls_client";
}
class TlsSocketClient: public Tls {
public:
TlsSocketClient() = default;
~TlsSocketClient() override
{
if (sock >= 0) {
::close(sock);
}
}
int send(const unsigned char *buf, size_t len) override
{
return ::send(sock, buf, len, 0);
}
int recv(unsigned char *buf, size_t len) override
{
return ::recv(sock, buf, len, 0);
}
bool connect(const char *host, int port)
{
addr_info addr(host, AF_INET, SOCK_STREAM);
if (!addr) {
ESP_LOGE(TAG, "Failed to resolve host");
return false;
}
sock = addr.get_sock();
if (sock < 0) {
ESP_LOGE(TAG, "Failed to create socket");
return false;
}
if (::connect(sock, addr.get_addr(port), sizeof(struct sockaddr)) < 0) {
ESP_LOGE(TAG, "Failed to connect %d", errno);
return false;
}
if (!init(is_server{false}, do_verify{false})) {
return false;
}
return handshake() == 0;
}
private:
int sock{-1};
/**
* RAII wrapper of the address_info
*/
struct addr_info {
struct addrinfo *ai {
nullptr
};
~addr_info()
{
freeaddrinfo(ai);
}
explicit addr_info(const char *host, int family, int type)
{
struct addrinfo hints {};
hints.ai_family = family;
hints.ai_socktype = type;
if (getaddrinfo(host, nullptr, &hints, &ai) < 0) {
freeaddrinfo(ai);
ai = nullptr;
}
}
explicit operator bool() const
{
return ai != nullptr;
}
struct sockaddr *get_addr(uint16_t port) const {
auto *p = (struct sockaddr_in *)ai->ai_addr;
p->sin_port = htons(port);
return (struct sockaddr *)p;
}
int get_sock() const
{
return socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
}
};
};
namespace {
void tls_client()
{
const unsigned char message[] = "Hello\n";
unsigned char reply[128];
TlsSocketClient client;
if (!client.connect("tcpbin.com", 4243)) {
ESP_LOGE(TAG, "Failed to connect! %d", errno);
return;
}
if (client.write(message, sizeof(message)) < 0) {
ESP_LOGE(TAG, "Failed to write!");
return;
}
int len = client.read(reply, sizeof(reply));
if (len < 0) {
ESP_LOGE(TAG, "Failed to read!");
return;
}
ESP_LOGI(TAG, "Successfully received: %.*s", len, reply);
}
} // namespace
#if CONFIG_IDF_TARGET_LINUX
/**
* Linux target: We're already connected, just run the client
*/
int main()
{
tls_client();
return 0;
}
#else
/**
* ESP32 chipsets: Need to initialize system components
* and connect to network
*/
#include "nvs_flash.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "esp_netif.h"
extern "C" void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
tls_client();
}
#endif