nim-libplum/libplum/libplum.nim
2026-07-13 17:14:11 +04:00

147 lines
4.7 KiB
Nim

# Copyright (c) 2026 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
# at your option.
# This file may not be copied, modified, or distributed except according to
# those terms.
import std/[os, sequtils, strutils]
const
rootPath = currentSourcePath.parentDir().parentDir().replace('\\', '/')
libplumPath = rootPath & "/vendor/libplum"
includePath = libplumPath & "/include/plum"
srcPath = libplumPath & "/src"
includes = @["-I" & includePath, "-I" & srcPath]
defs = @["-DPLUM_STATIC", "-DPLUM_EXPORTS", "-DRELEASE=1", "-D_GNU_SOURCE"]
pdefs =
when defined(windows):
@["-DWIN32_LEAN_AND_MEAN"]
else:
@[]
flags* = (includes & defs & pdefs).mapIt(it.quoteShell()).join(" ")
{.localPassC: flags.}
when defined(windows):
{.passl: "-lws2_32 -liphlpapi -lbcrypt".}
else:
{.passl: "-lpthread".}
{.compile(rootPath & "/libplum_units.c", flags).}
{.compile(srcPath & "/http.c", flags).}
{.compile(srcPath & "/upnp.c", flags).}
const
PLUM_ERR_SUCCESS* = cint(0)
PLUM_ERR_INVALID* = cint(-1)
PLUM_ERR_FAILED* = cint(-2)
PLUM_ERR_NOT_AVAIL* = cint(-3)
PLUM_MAX_HOST_LEN* = 256
PLUM_MAX_ADDRESS_LEN* = 64
# Import plum enums with cint size
type
plum_log_level_t* {.
importc: "plum_log_level_t", header: "plum.h", size: sizeof(cint)
.} = enum
PLUM_LOG_LEVEL_VERBOSE
PLUM_LOG_LEVEL_DEBUG
PLUM_LOG_LEVEL_INFO
PLUM_LOG_LEVEL_WARN
PLUM_LOG_LEVEL_ERROR
PLUM_LOG_LEVEL_FATAL
PLUM_LOG_LEVEL_NONE
plum_ip_protocol_t* {.
importc: "plum_ip_protocol_t", header: "plum.h", size: sizeof(cint)
.} = enum
PLUM_IP_PROTOCOL_TCP
PLUM_IP_PROTOCOL_UDP
plum_protocol_t* {.importc: "plum_protocol_t", header: "plum.h", size: sizeof(cint).} = enum
PLUM_PROTOCOL_ANY
PLUM_PROTOCOL_PCP
PLUM_PROTOCOL_UPNP
plum_state_t* {.importc: "plum_state_t", header: "plum.h", size: sizeof(cint).} = enum
PLUM_STATE_DESTROYED
PLUM_STATE_PENDING
PLUM_STATE_SUCCESS
PLUM_STATE_FAILURE
PLUM_STATE_DESTROYING
plum_mapping_protocol_t* {.
importc: "plum_mapping_protocol_t", header: "plum.h", size: sizeof(cint)
.} = enum
PLUM_MAPPING_PROTOCOL_UNKNOWN
PLUM_MAPPING_PROTOCOL_PCP
PLUM_MAPPING_PROTOCOL_NATPMP
PLUM_MAPPING_PROTOCOL_UPNP
PLUM_MAPPING_PROTOCOL_DIRECT
# Define the callback to receive the plum logs
plum_log_callback_t* = proc(level: plum_log_level_t, message: cstring) {.cdecl.}
# Define the config struct, passed by copy (usual for struct).
plum_config_t* {.importc: "plum_config_t", header: "plum.h", bycopy.} = object
log_level* {.importc: "log_level".}: plum_log_level_t
log_callback* {.importc: "log_callback".}: plum_log_callback_t
dummytls_domain* {.importc: "dummytls_domain".}: cstring
discover_timeout* {.importc: "discover_timeout".}: cint
# msecs, 0 means use default (10000)
mapping_timeout* {.importc: "mapping_timeout".}: cint
# msecs, 0 means use default (10000)
recheck_period* {.importc: "recheck_period".}: cint
# msecs, 0 means use default (300000)
protocol* {.importc: "protocol".}: plum_protocol_t # PLUM_PROTOCOL_ANY means try all
# Define the mapping struct, passed by copy (usual for struct).
# The user_ptr is a pointer to the MappingHandle in order to receive the result
plum_mapping_t* {.importc: "plum_mapping_t", header: "plum.h", bycopy.} = object
protocol* {.importc: "protocol".}: plum_ip_protocol_t
mapping_protocol* {.importc: "mapping_protocol".}: plum_mapping_protocol_t
internal_port* {.importc: "internal_port".}: uint16
external_port* {.importc: "external_port".}: uint16
external_host* {.importc: "external_host".}: array[PLUM_MAX_HOST_LEN, char]
user_ptr* {.importc: "user_ptr".}: pointer
# Define the callback to receive the mapping result
plum_mapping_callback_t* =
proc(id: cint, state: plum_state_t, mapping: ptr plum_mapping_t) {.cdecl.}
# Import plum functions
{.push raises: [].}
proc plum_init*(
config: ptr plum_config_t
): cint {.importc: "plum_init", header: "plum.h".}
proc plum_cleanup*(): cint {.importc: "plum_cleanup", header: "plum.h".}
proc plum_create_mapping*(
mapping: ptr plum_mapping_t, callback: plum_mapping_callback_t
): cint {.importc: "plum_create_mapping", header: "plum.h".}
proc plum_query_mapping*(
id: cint, state: ptr plum_state_t, mapping: ptr plum_mapping_t
): cint {.importc: "plum_query_mapping", header: "plum.h".}
proc plum_destroy_mapping*(
id: cint
): cint {.importc: "plum_destroy_mapping", header: "plum.h".}
proc plum_get_local_address*(
buffer: cstring, size: csize_t
): cint {.importc: "plum_get_local_address", header: "plum.h".}
{.pop.}