| /*
* sai-resource
*
* Copyright (C) 2019 - 2021 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include <libwebsockets.h>
#include <string.h>
#include <signal.h>
#include "../common/include/private.h"
#include "r-private.h"
typedef struct sair_resource {
struct lws_ss_handle *ss;
void *opaque_data;
} sair_resource_t;
static lws_ss_state_return_t
sair_lp_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
{
/*
* Possibly: 1) nothing comes and we get timed out by whatever spawned
* us (usually ctest), 2) we get the lease acknowledgement from
* sai-server and can exit successfully, or 3) we get an explicit deny
* from sai-server (eg, unknown well-known resource name).
*
* He sends us a JSON with an optional "error" description member,
* "result" being 0 means it went OK, anything else we failed.
*/
lwsl_hexdump_notice(buf, len);
return LWSSSSRET_OK;
}
static lws_ss_state_return_t
sair_lp_tx(void *userobj, lws_ss_tx_ordinal_t ord, uint8_t *buf, size_t *len,
int *flags)
{
// sair_resource_t *lp = (sair_resource_t *)userobj;
if (!msg[0])
return LWSSSSRET_TX_DONT_SEND; /* nothing to send */
*flags = LWSSS_FLAG_SOM | LWSSS_FLAG_EOM;
if (*len > strlen(msg))
*len = strlen(msg);
memcpy(buf, msg, *len);
msg[0] = '\0';
lwsl_notice("%s: issuing requisition %s\n", __func__, msg);
return LWSSSSRET_OK;
}
static lws_ss_state_return_t
sair_lp_state(void *userobj, void *sh, lws_ss_constate_t state,
lws_ss_tx_ordinal_t ack)
{
sair_resource_t *lp = (sair_resource_t *)userobj;
lwsl_info("%s: %s, ord 0x%x\n", __func__, lws_ss_state_name(state),
(unsigned int)ack);
switch (state) {
case LWSSSCS_CONNECTED:
return lws_ss_request_tx(lp->ss);
case LWSSSCS_ALL_RETRIES_FAILED:
case LWSSSCS_DISCONNECTED:
/*
* That's it for us
*/
interrupted = 1;
break;
default:
break;
}
return LWSSSSRET_OK;
}
static const lws_ss_info_t ssi_sair_resource = {
.handle_offset = offsetof(sair_resource_t, ss),
.opaque_user_data_offset = offsetof(sair_resource_t, opaque_data),
.rx = sair_lp_rx,
.tx = sair_lp_tx,
.state = sair_lp_state,
.user_alloc = sizeof(sair_resource_t),
.streamtype = "resproxy"
};
struct lws_ss_handle *
sair_ss_from_env(struct lws_context *context, const char *env_name)
{
char *e = getenv(env_name);
struct lws_ss_handle *h;
if (!e) {
lwsl_notice("%s: no env var %s\n", __func__, env_name);
return NULL;
}
lwsl_notice("%s: connecting to %s\n", __func__, e);
if (lws_ss_create(context, 0, &ssi_sair_resource, 0, &h, NULL, NULL)) {
lwsl_err("%s: failed to create SS for %s\n", __func__, env_name);
return NULL;
}
if (lws_ss_set_metadata(h, "sockpath", e, strlen(e)))
lwsl_err("%s: unable to set metadata\n", __func__);
if (lws_ss_client_connect(h)) {
lws_ss_destroy(&h);
return NULL;
}
return h;
}
|