Skip to content

Commit

Permalink
Add support for net:getaddrinfo/1,2 on Pico-W
Browse files Browse the repository at this point in the history
Also factorize common functions

Signed-off-by: Paul Guyot <pguyot@kallisys.net>
  • Loading branch information
pguyot committed Nov 3, 2023
1 parent 6643ea7 commit 9f20cce
Show file tree
Hide file tree
Showing 11 changed files with 488 additions and 94 deletions.
77 changes: 77 additions & 0 deletions src/libAtomVM/inet.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* This file is part of AtomVM.
*
* Copyright 2023 by Paul Guyot <pguyot@kallisys.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
*/

#include "inet.h"
#include "term.h"

#include <port.h>

static const AtomStringIntPair inet_domain_table[] = {
{ ATOM_STR("\x4", "inet"), InetDomain },
SELECT_INT_DEFAULT(InetInvalidDomain)
};

enum inet_domain inet_atom_to_domain(term domain, GlobalContext *global)
{
return interop_atom_term_select_int(inet_domain_table, domain, global);
}

static const AtomStringIntPair inet_type_table[] = {
{ ATOM_STR("\x6", "stream"), InetStreamType },
{ ATOM_STR("\x5", "dgram"), InetDgramType },
SELECT_INT_DEFAULT(InetInvalidType)
};

enum inet_type inet_atom_to_type(term type, GlobalContext *global)
{
return interop_atom_term_select_int(inet_type_table, type, global);
}

static const AtomStringIntPair inet_protocol_table[] = {
{ ATOM_STR("\x2", "ip"), InetIpProtocol },
{ ATOM_STR("\x3", "tcp"), InetTcpProtocol },
{ ATOM_STR("\x3", "udp"), InetUdpProtocol },
SELECT_INT_DEFAULT(InetInvalidProtocol)
};

enum inet_protocol inet_atom_to_protocol(term protocol, GlobalContext *global)
{
return interop_atom_term_select_int(inet_protocol_table, protocol, global);
}

uint32_t inet_addr4_to_uint32(term addr_tuple)
{
return ((term_to_int32(term_get_tuple_element(addr_tuple, 0)) & 0xFF) << 24)
| ((term_to_int32(term_get_tuple_element(addr_tuple, 1)) & 0xFF) << 16)
| ((term_to_int32(term_get_tuple_element(addr_tuple, 2)) & 0xFF) << 8)
| (term_to_int32(term_get_tuple_element(addr_tuple, 3)) & 0xFF);
}

#define INET_ADDR4_TUPLE_SIZE TUPLE_SIZE(4)

term inet_make_addr4(uint32_t addr, Heap *heap)
{
term result = term_alloc_tuple(4, heap);
term_put_tuple_element(result, 0, term_from_int32((addr >> 24) & 0xFF));
term_put_tuple_element(result, 1, term_from_int32((addr >> 16) & 0xFF));
term_put_tuple_element(result, 2, term_from_int32((addr >> 8) & 0xFF));
term_put_tuple_element(result, 3, term_from_int32(addr & 0xFF));
return result;
}
99 changes: 99 additions & 0 deletions src/libAtomVM/inet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* This file is part of AtomVM.
*
* Copyright 2023 by Paul Guyot <pguyot@kallisys.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
*/

#ifndef _INET_COMMON_H_
#define _INET_COMMON_H_

#include <interop.h>
#include <memory.h>

#ifdef __cplusplus
extern "C" {
#endif

enum inet_domain
{
InetInvalidDomain = 0,
InetDomain
};

/**
* @brief Parse an inet domain atom
* @param domain the inet domain atom
* @param global the global context
* @returns InetDomain or InetInvalidDomain
*/
enum inet_domain inet_atom_to_domain(term domain, GlobalContext *global);

enum inet_type
{
InetInvalidType = 0,
InetStreamType,
InetDgramType
};

/**
* @brief Parse an inet type
* @param type the inet type atom
* @param global the global context
* @returns the parsed type
*/
enum inet_type inet_atom_to_type(term type, GlobalContext *global);

enum inet_protocol
{
InetInvalidProtocol = 0,
InetIpProtocol,
InetTcpProtocol,
InetUdpProtocol
};

/**
* @brief Parse an inet protocol
* @param type the inet protocol atom
* @param global the global context
* @returns the parsed protocol
*/
enum inet_protocol inet_atom_to_protocol(term protocol, GlobalContext *global);

/**
* @brief Parse an inet IPv4 address tuple
* @param addr_tuple the tuple to parse
* @returns the address as a uint32_t, in host order
*/
uint32_t inet_addr4_to_uint32(term addr_tuple);

#define INET_ADDR4_TUPLE_SIZE TUPLE_SIZE(4)

/**
* @brief Make an inet IPv4 address tuple
* @param addr the address to make as a tuple, as a uint32_t in host order
* @param heap the heap to build the tuple in
* @returns the tuple
* @details this function requires that at least INET_ADDR4_TUPLE_SIZE terms
* are free on the heap.
*/
term inet_make_addr4(uint32_t addr, Heap *heap);

#ifdef __cplusplus
}
#endif

#endif
14 changes: 2 additions & 12 deletions src/libAtomVM/otp_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <context.h>
#include <defaultatoms.h>
#include <globalcontext.h>
#include <inet.h>
#include <interop.h>
#include <nifs.h>
#include <otp_net.h>
Expand Down Expand Up @@ -53,17 +54,6 @@ static const AtomStringIntPair type_table[] = {
// utilities
//

static term socket_tuple_from_addr(Context *ctx, uint32_t addr)
{
term terms[4];
terms[0] = term_from_int32((addr >> 24) & 0xFF);
terms[1] = term_from_int32((addr >> 16) & 0xFF);
terms[2] = term_from_int32((addr >> 8) & 0xFF);
terms[3] = term_from_int32(addr & 0xFF);

return port_create_tuple_n(ctx, 4, terms);
}

static inline term make_error_tuple(term reason, Context *ctx)
{
term error_tuple = term_alloc_tuple(2, &ctx->heap);
Expand Down Expand Up @@ -107,7 +97,7 @@ static term eai_errno_to_term(int err, GlobalContext *glb)

static inline term make_address(Context *ctx, struct sockaddr_in *addr)
{
return socket_tuple_from_addr(ctx, ntohl(addr->sin_addr.s_addr));
return inet_make_addr4(ntohl(addr->sin_addr.s_addr), &ctx->heap);
}

//
Expand Down
Loading

0 comments on commit 9f20cce

Please sign in to comment.