I am trying to make an nrfcloud api rest call from the nrf7002dk after connecting to my access point.
I combined the sta and http_get examples. run_http_queries is what initiates the https connection and request.
/*
* Copyright (c) 2017 Linaro Limited
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdlib.h>
#if !defined(__ZEPHYR__) || defined(CONFIG_POSIX_API)
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#else
#include <zephyr/net/socket.h>
#include <zephyr/kernel.h>
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
#include <zephyr/net/tls_credentials.h>
#include "ca_certificate.h"
#endif
#endif
/* HTTP server to connect to */
#define HTTP_HOST "api.nrfcloud.com"
/* Port to connect to, as string */
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
#define HTTP_PORT "443"
#else
// #define HTTP_PORT "80"
#define HTTP_PORT "443"
#endif
/* HTTP path to request */
#define HTTP_PATH "/v1/account/service-evaluation-token"
#define SSTRLEN(s) (sizeof(s) - 1)
#define CHECK(r) { if (r == -1) { printf("Error: " #r "\n"); exit(1); } }
#define REQUEST "GET " HTTP_PATH " HTTP/1.1\
\r\nHost: " HTTP_HOST "\
\r\nContent-Type: text/plain\
\r\nAuthorization: Bearer xxxxxxx...\
\r\nContent-Length: 1\r\n\r\n{"
#define GET_REQUEST "GET /v1/account/service-evaluation-token HTTP/1.1\r\n\
Host: api.nrfcloud.com:443\r\n\
Content-Type: text/plain\r\n\
Authorization: Bearer xxxxxxx......\r\n\
Content-Length: 1\r\n\
\r\n\
{"
static char response[1024];
void dump_addrinfo(const struct addrinfo *ai)
{
printf("addrinfo @%p: ai_family=%d, ai_socktype=%d, ai_protocol=%d, "
"sa_family=%d, sin_port=%x\n",
ai, ai->ai_family, ai->ai_socktype, ai->ai_protocol,
ai->ai_addr->sa_family,
((struct sockaddr_in *)ai->ai_addr)->sin_port);
}
int run_http_queries(void)
{
static struct addrinfo hints;
struct addrinfo *res;
int st, sock;
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
tls_credential_add(CA_CERTIFICATE_TAG, TLS_CREDENTIAL_CA_CERTIFICATE,
ca_certificate, sizeof(ca_certificate));
#endif
printf("Preparing HTTP GET request for " HTTP_HOST
":" HTTP_PORT HTTP_PATH "\n");
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
st = getaddrinfo(HTTP_HOST, HTTP_PORT, &hints, &res);
printf("getaddrinfo status: %d\n", st);
if (st != 0) {
printf("Unable to resolve address, quitting\n");
return 0;
}
#if 0
for (; res; res = res->ai_next) {
dump_addrinfo(res);
}
#endif
dump_addrinfo(res);
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
sock = socket(res->ai_family, res->ai_socktype, IPPROTO_TLS_1_2);
#else
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
// sock = socket(res->ai_family, res->ai_socktype, IPPROTO_TLS_1_2);
#endif
CHECK(sock);
printf("sock = %d\n", sock);
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
sec_tag_t sec_tag_opt[] = {
CA_CERTIFICATE_TAG,
};
// CHECK(setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST,
// sec_tag_opt, sizeof(sec_tag_opt)));
// int verify = 2;
// CHECK(setsockopt(sock, SOL_TLS, TLS_PEER_VERIFY, &verify, sizeof(verify)));
CHECK(setsockopt(sock, SOL_TLS, TLS_HOSTNAME,
HTTP_HOST, sizeof(HTTP_HOST)))
#endif
CHECK(connect(sock, res->ai_addr, res->ai_addrlen));
// CHECK(send(sock, REQUEST, SSTRLEN(REQUEST), 0));
CHECK(send(sock, GET_REQUEST, SSTRLEN(GET_REQUEST), 0));
printf("Response:\n\n");
while (1) {
int len = recv(sock, response, sizeof(response) - 1, 0);
if (len < 0) {
printf("Error reading response\n");
return 0;
}
if (len == 0) {
break;
}
response[len] = 0;
printf("%s", response);
}
printf("\n");
(void)close(sock);
return 0;
}
I've seen nrf9160 examples use the sec_tag to pull the certs and create the https connection before the actual request is sent.
However, with postman I am able to send nrfcloud rest requests without a certificate using the bearer token that I get from the service evaluation token which is what I'm trying to do on the nrf7002dk using just the bearer token.