Berry tcpserver

This commit is contained in:
Stephan Hadinger 2022-07-07 19:28:17 +02:00
parent 7a684be3d3
commit 5e758db898
9 changed files with 1253 additions and 1092 deletions

View File

@ -199,6 +199,7 @@ be_extern_native_class(md5);
be_extern_native_class(udp);
be_extern_native_class(webclient);
be_extern_native_class(tcpclient);
be_extern_native_class(tcpserver);
be_extern_native_class(energy_struct);
// BLE
be_extern_native_class(MI32);
@ -246,6 +247,9 @@ BERRY_LOCAL bclass_array be_class_table = {
&be_native_class(webclient),
&be_native_class(tcpclient),
#endif // USE_WEBCLIENT
#ifdef USE_BERRY_TCPSERVER
&be_native_class(tcpserver),
#endif // USE_BERRY_TCPSERVER
#ifdef USE_WS2812
&be_native_class(Leds_ntv),
&be_native_class(Leds),

View File

@ -235,6 +235,7 @@ extern const bcstring be_const_str__validate;
extern const bcstring be_const_str__write;
extern const bcstring be_const_str_a;
extern const bcstring be_const_str_abs;
extern const bcstring be_const_str_accept;
extern const bcstring be_const_str_acos;
extern const bcstring be_const_str_active_otadata;
extern const bcstring be_const_str_adc_config;
@ -484,6 +485,7 @@ extern const bcstring be_const_str_h;
extern const bcstring be_const_str_has;
extern const bcstring be_const_str_has_arg;
extern const bcstring be_const_str_has_factory;
extern const bcstring be_const_str_hasclient;
extern const bcstring be_const_str_height_def;
extern const bcstring be_const_str_hex;
extern const bcstring be_const_str_hour;
@ -787,6 +789,7 @@ extern const bcstring be_const_str_tasmota_X2Eget_light_X28_X29_X20is_X20depreca
extern const bcstring be_const_str_tasmota_X2Eset_light_X28_X29_X20is_X20deprecated_X2C_X20use_X20light_X2Eset_X28_X29;
extern const bcstring be_const_str_tasmota_log_reader;
extern const bcstring be_const_str_tcpclient;
extern const bcstring be_const_str_tcpserver;
extern const bcstring be_const_str_tele;
extern const bcstring be_const_str_test;
extern const bcstring be_const_str_the_X20second_X20argument_X20is_X20not_X20a_X20function;

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,16 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_tcpclient_map) {
{ be_const_key(write, 8), be_const_func(wc_tcp_write) },
{ be_const_key(close, -1), be_const_func(wc_tcp_close) },
{ be_const_key(connected, 3), be_const_func(wc_tcp_connected) },
{ be_const_key(deinit, -1), be_const_func(wc_tcp_deinit) },
{ be_const_key(_X2Ew, 0), be_const_var(0) },
{ be_const_key(close, -1), be_const_func(wc_tcp_close) },
{ be_const_key(connected, 0), be_const_func(wc_tcp_connected) },
{ be_const_key(_X2Ep, -1), be_const_var(0) },
{ be_const_key(available, 8), be_const_func(wc_tcp_available) },
{ be_const_key(init, -1), be_const_func(wc_tcp_init) },
{ be_const_key(readbytes, -1), be_const_func(wc_tcp_readbytes) },
{ be_const_key(connect, -1), be_const_func(wc_tcp_connect) },
{ be_const_key(available, -1), be_const_func(wc_tcp_available) },
{ be_const_key(read, -1), be_const_func(wc_tcp_read) },
{ be_const_key(write, -1), be_const_func(wc_tcp_write) },
{ be_const_key(read, 3), be_const_func(wc_tcp_read) },
};
static be_define_const_map(

View File

@ -0,0 +1,22 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_tcpserver_map) {
{ be_const_key(init, -1), be_const_ctype_func(tcpserver_init) },
{ be_const_key(accept, -1), be_const_ctype_func(tcpserver_accept) },
{ be_const_key(_p, -1), be_const_var(0) },
{ be_const_key(close, 0), be_const_ctype_func(tcpserver_close) },
{ be_const_key(deinit, 5), be_const_ctype_func(tcpserver_deinit) },
{ be_const_key(hasclient, -1), be_const_ctype_func(tcpserver_hasclient) },
};
static be_define_const_map(
be_class_tcpserver_map,
6
);
BE_EXPORT_VARIABLE be_define_const_class(
be_class_tcpserver,
1,
NULL,
tcpserver
);

View File

@ -30,7 +30,7 @@ void be_load_tcpclient_lib(bvm *vm) {
/* @const_object_info_begin
class be_class_tcpclient (scope: global, name: tcpclient) {
.w, var
.p, var
init, func(wc_tcp_init)
deinit, func(wc_tcp_deinit)

View File

@ -0,0 +1,32 @@
/********************************************************************
* Tcp socket
*******************************************************************/
#include "be_constobj.h"
#include "be_mapping.h"
#include "be_ctypes.h"
#ifdef USE_BERRY_TCPSERVER
extern const void * tcpserver_init(struct bvm *vm, int32_t port); BE_FUNC_CTYPE_DECLARE(tcpserver_init, "+_p", "@i")
extern void tcpserver_deinit(void *server_tcp); BE_FUNC_CTYPE_DECLARE(tcpserver_deinit, "", ".")
extern void tcpserver_close(void *server); BE_FUNC_CTYPE_DECLARE(tcpserver_close, "", ".")
extern bbool tcpserver_hasclient(void *server); BE_FUNC_CTYPE_DECLARE(tcpserver_hasclient, "b", ".")
extern void * tcpserver_accept(struct bvm *vm, void *server); BE_FUNC_CTYPE_DECLARE(tcpserver_accept, "tcpclient", "@.")
#include "be_fixed_be_class_tcpserver.h"
/* @const_object_info_begin
class be_class_tcpserver (scope: global, name: tcpserver) {
_p, var
init, ctype_func(tcpserver_init)
deinit, ctype_func(tcpserver_deinit)
close, ctype_func(tcpserver_close)
hasclient, ctype_func(tcpserver_hasclient)
accept, ctype_func(tcpserver_accept)
}
@const_object_info_end */
#endif // USE_BERRY_TCPSERVER

View File

@ -0,0 +1,81 @@
/*
xdrv_52_3_berry_tcpserver.ino - Berry scripting language, tcp socket and server class
Copyright (C) 2022 Stephan Hadinger, Berry language by Guan Wenliang https://github.com/Skiars/berry
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// also includes tcp_client
#ifdef USE_BERRY
#ifdef USE_BERRY_TCPSERVER
#include <berry.h>
/*********************************************************************************************\
* Native functions mapped to Berry functions
*
\*********************************************************************************************/
extern "C" {
const void* tcpserver_init(struct bvm *vm, int32_t tcp_port) {
if (tcp_port > 0 && tcp_port < 65535) {
WiFiServer *server_tcp = new WiFiServer(tcp_port);
server_tcp->begin(); // start TCP server
server_tcp->setNoDelay(true);
return server_tcp;
} else {
be_raisef(vm, "value_error","Invalid port %d", tcp_port);
}
return NULL;
}
void tcpserver_deinit(void *server) {
WiFiServer *server_tcp = (WiFiServer*) server;
if (server_tcp) {
server_tcp->stop();
delete server_tcp;
}
}
void tcpserver_close(void *server) {
WiFiServer *server_tcp = (WiFiServer*) server;
if (server_tcp) {
server_tcp->stop();
}
}
bbool tcpserver_hasclient(void *server) {
WiFiServer *server_tcp = (WiFiServer*) server;
return server_tcp->hasClient();
}
void * tcpserver_accept(struct bvm *vm, void *server) {
WiFiServer *server_tcp = (WiFiServer*) server;
WiFiClient * client_ptr = nullptr;
if (server_tcp->hasClient()) {
WiFiClient new_client = server_tcp->available();
AddLog(LOG_LEVEL_INFO, "BRY: Got connection from %s", new_client.remoteIP().toString().c_str());
client_ptr = new WiFiClient();
*client_ptr = new_client;
} else {
be_raise(vm, "internal_error", "tcpserver has no client connected");
}
return client_ptr;
}
}
#endif // USE_BERRY_TCPSERVER
#endif // USE_BERRY

View File

@ -98,9 +98,15 @@ extern "C" {
int32_t wc_tcp_init(struct bvm *vm);
int32_t wc_tcp_init(struct bvm *vm) {
WiFiClient * wcl = new WiFiClient();
int32_t argc = be_top(vm);
WiFiClient * wcl;
if (argc >= 2 && be_iscomptr(vm, 2)) {
wcl = (WiFiClient*) be_tocomptr(vm, 2);
} else {
wcl = new WiFiClient();
}
be_pushcomptr(vm, (void*) wcl);
be_setmember(vm, 1, ".w");
be_setmember(vm, 1, ".p");
be_return_nil(vm);
}
@ -118,6 +124,14 @@ extern "C" {
return (WiFiClient*) p;
}
// same but using `.p` argument
WiFiClient * wc_getwificlient_p(struct bvm *vm) {
be_getmember(vm, 1, ".p");
void *p = be_tocomptr(vm, -1);
be_pop(vm, 1);
return (WiFiClient*) p;
}
int32_t wc_deinit(struct bvm *vm);
int32_t wc_deinit(struct bvm *vm) {
// int32_t argc = be_top(vm); // Get the number of arguments
@ -133,9 +147,9 @@ extern "C" {
int32_t wc_tcp_deinit(struct bvm *vm);
int32_t wc_tcp_deinit(struct bvm *vm) {
WiFiClient * wcl = wc_getwificlient(vm);
WiFiClient * wcl = wc_getwificlient_p(vm);
if (wcl != nullptr) { delete wcl; }
be_setmember(vm, 1, ".w");
be_setmember(vm, 1, ".p");
be_return_nil(vm);
}
@ -172,7 +186,7 @@ extern "C" {
int32_t wc_tcp_connect(struct bvm *vm) {
int32_t argc = be_top(vm);
if (argc >= 3 && be_isstring(vm, 2) && be_isint(vm, 3)) {
WiFiClient * tcp = wc_getwificlient(vm);
WiFiClient * tcp = wc_getwificlient_p(vm);
const char * address = be_tostring(vm, 2);
int32_t port = be_toint(vm, 3);
int32_t timeout = USE_BERRY_WEBCLIENT_TIMEOUT; // default timeout of 2 seconds
@ -198,7 +212,7 @@ extern "C" {
// tcp.close(void) -> nil
int32_t wc_tcp_close(struct bvm *vm);
int32_t wc_tcp_close(struct bvm *vm) {
WiFiClient * tcp = wc_getwificlient(vm);
WiFiClient * tcp = wc_getwificlient_p(vm);
tcp->stop();
be_return_nil(vm);
}
@ -206,7 +220,7 @@ extern "C" {
// tcp.available(void) -> int
int32_t wc_tcp_available(struct bvm *vm);
int32_t wc_tcp_available(struct bvm *vm) {
WiFiClient * tcp = wc_getwificlient(vm);
WiFiClient * tcp = wc_getwificlient_p(vm);
int32_t available = tcp->available();
be_pushint(vm, available);
be_return(vm);
@ -295,7 +309,7 @@ extern "C" {
// tcp.connected(void) -> bool
int32_t wc_tcp_connected(struct bvm *vm);
int32_t wc_tcp_connected(struct bvm *vm) {
WiFiClient * tcp = wc_getwificlient(vm);
WiFiClient * tcp = wc_getwificlient_p(vm);
be_pushbool(vm, tcp->connected());
be_return(vm); /* return code */
}
@ -305,7 +319,7 @@ extern "C" {
int32_t wc_tcp_write(struct bvm *vm) {
int32_t argc = be_top(vm);
if (argc >= 2 && (be_isstring(vm, 2) || be_isbytes(vm, 2))) {
WiFiClient * tcp = wc_getwificlient(vm);
WiFiClient * tcp = wc_getwificlient_p(vm);
const char * buf = nullptr;
size_t buf_len = 0;
if (be_isstring(vm, 2)) { // string
@ -324,7 +338,7 @@ extern "C" {
// tcp.read() -> string
int32_t wc_tcp_read(struct bvm *vm);
int32_t wc_tcp_read(struct bvm *vm) {
WiFiClient * tcp = wc_getwificlient(vm);
WiFiClient * tcp = wc_getwificlient_p(vm);
int32_t max_read = -1; // by default read as much as we can
if (be_top(vm) >= 2 && be_isint(vm, 2)) {
max_read = be_toint(vm, 2);
@ -346,7 +360,7 @@ extern "C" {
// tcp.readbytes() -> bytes
int32_t wc_tcp_readbytes(struct bvm *vm);
int32_t wc_tcp_readbytes(struct bvm *vm) {
WiFiClient * tcp = wc_getwificlient(vm);
WiFiClient * tcp = wc_getwificlient_p(vm);
int32_t max_read = -1; // by default read as much as we can
if (be_top(vm) >= 2 && be_isint(vm, 2)) {
max_read = be_toint(vm, 2);