219 lines
5.9 KiB
C
219 lines
5.9 KiB
C
/* ************************************************************************** */
|
|
/* _____ _ */
|
|
/* core/_init.c |_ _|__ _ _| |__ ___ _ _ */
|
|
/* | Project: libp7 | |/ _ \| | | | '_ \ / _ \ | | | */
|
|
/* | | (_) | |_| | | | | __/ |_| | */
|
|
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
|
/* Last updated: 2017/01/04 15:01:48 |___/ */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
#include <libp7/internals.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/* simple global containing handle size */
|
|
const size_t p7_handle_size = sizeof(p7_handle_t);
|
|
|
|
/* ************************************************************************** */
|
|
/* Get and set handler data */
|
|
/* ************************************************************************** */
|
|
/**
|
|
* p7_get_response:
|
|
* Get response from handle.
|
|
*
|
|
* The handle has an unknown structure for the user.
|
|
*
|
|
* @arg handle the handle.
|
|
* @return the stream.
|
|
*/
|
|
|
|
const p7_packet_t *p7_get_response(p7_handle_t *handle)
|
|
{
|
|
return (handle->_response);
|
|
}
|
|
|
|
/**
|
|
* p7_get_stream:
|
|
* Get stream from handle.
|
|
*
|
|
* Same reason than above.
|
|
*
|
|
* @arg handle the handle.
|
|
* @return the stream.
|
|
*/
|
|
|
|
const p7_stream_t *p7_get_stream(p7_handle_t *handle)
|
|
{
|
|
return (handle->_stream);
|
|
}
|
|
|
|
/**
|
|
* p7_get_info:
|
|
* Get server info.
|
|
*
|
|
* @arg handle the handle.
|
|
* @return the server info.
|
|
*/
|
|
|
|
const p7_server_t *p7_get_info(p7_handle_t *handle)
|
|
{
|
|
return (&handle->_server);
|
|
}
|
|
|
|
/* ************************************************************************** */
|
|
/* Initialization */
|
|
/* ************************************************************************** */
|
|
/**
|
|
* start:
|
|
* Start the communication.
|
|
*
|
|
* @arg handle the handle.
|
|
* @return the error, if any.
|
|
*/
|
|
|
|
static int start(p7_handle_t *handle, int check)
|
|
{
|
|
int err = 0;
|
|
log_info("so we're active? let's do what active people do then!");
|
|
|
|
/* send initial check */
|
|
if (check) {
|
|
log_info("sending initial check packet");
|
|
if ((err = p7_send_ini_check(handle))) {
|
|
log_fatal("couldn't send check/didn't receive answer");
|
|
return (err);
|
|
} else if (response.type != p7_pt_ack) {
|
|
log_fatal("received packet wasn't ack, ask your dentist");
|
|
return (p7_error_unknown);
|
|
}
|
|
#if LOGLEVEL <= ll_info
|
|
} else {
|
|
log_info("skipping initial check, we suppose already initialized");
|
|
#endif
|
|
}
|
|
|
|
/* discover environment */
|
|
log_info("checkin' up da environment");
|
|
if ((err = p7_send_cmdsys_getinfo(handle))) {
|
|
log_fatal("couldn't send env query/receive answer");
|
|
return (err);
|
|
} else if (response.type != p7_pt_ack || !response.extended) {
|
|
log_fatal("response to env query wasn't an extended ack packet");
|
|
return (p7_error_unknown);
|
|
}
|
|
|
|
/* save server */
|
|
handle->_server = response.info;
|
|
|
|
/* get environment based on sent hardware id */
|
|
handle->_env = p7_get_env(handle->_server.hwid);
|
|
log_info("environment is '%s'", handle->_env->name);
|
|
|
|
/* no error */
|
|
return (0);
|
|
}
|
|
|
|
/**
|
|
* p7_sinit:
|
|
* Initialize libp7 with a P7 stream.
|
|
*
|
|
* @arg h the handle to create
|
|
* @arg flags the flags.
|
|
* @arg name the name of the handle.
|
|
* @arg dstream the P7 stream to use.
|
|
* @return the error (0 if ok)
|
|
*/
|
|
|
|
int p7_sinit(p7_handle_t **h, unsigned int flags,
|
|
const char *name, p7_stream_t dstream)
|
|
{
|
|
int err = 0;
|
|
|
|
/* allocate handle */
|
|
int alloc = !*h;
|
|
if (alloc) {
|
|
logr_info("looks like the handle wasn't allocated! let's make one.");
|
|
*h = NULL;
|
|
if (!(*h = malloc(sizeof(p7_handle_t))))
|
|
return (p7_error_alloc);
|
|
}
|
|
|
|
/* initialize handle */
|
|
p7_handle_t *handle = *h;
|
|
memset(handle, 0, sizeof(p7_handle_t));
|
|
handle->_wasalloc = alloc;
|
|
handle->_stream_data = dstream;
|
|
handle->_stream = &handle->_stream_data;
|
|
handle->_response = &handle->_response_data;
|
|
|
|
/* prepare the name */
|
|
if (!name) handle->_name[0] = 0;
|
|
else {
|
|
handle->_name[0] = ' ';
|
|
strncpy(&handle->_name[1], name, 8);
|
|
handle->_name[9] = 0;
|
|
}
|
|
log_info("handle prepared, masta!");
|
|
|
|
/* set the initial communication settings */
|
|
log_info("initializing stream settings");
|
|
p7_setcomm(handle->_stream, P7_B9600, P7_PARITY_NONE, P7_TWOSTOPBITS);
|
|
|
|
/* starting as active */
|
|
handle->_active = flags & P7_ACTIVE;
|
|
handle->_terminated = 0;
|
|
handle->_term = flags & P7_TERM;
|
|
/* initialize environment */
|
|
handle->_env = NULL;
|
|
/* initialize stupid things */
|
|
handle->_shifted = 0;
|
|
handle->_send_buffers_size[0] = 0;
|
|
handle->_send_buffers_size[1] = 0;
|
|
handle->_send_buffer_id = 0;
|
|
|
|
/* if active, start */
|
|
if (handle->_active && (err = start(handle, flags & P7_CHECK))) {
|
|
handle->_term = P7_TERM;
|
|
p7_exit(*h); *h = NULL;
|
|
return (err);
|
|
}
|
|
|
|
/* initialization went alright */
|
|
return (0);
|
|
}
|
|
|
|
/* ************************************************************************** */
|
|
/* De-initialization */
|
|
/* ************************************************************************** */
|
|
/**
|
|
* p7_exit:
|
|
* De-initialize libp7.
|
|
*
|
|
* @arg handle the handle to free.
|
|
* @arg wasalloc should we free the handle?
|
|
*/
|
|
|
|
void p7_exit(p7_handle_t *handle)
|
|
{
|
|
log_info("exit is called.");
|
|
/* check if handle is already freed */
|
|
if (!handle) return;
|
|
log_info("and handle is still there, so let's go!");
|
|
|
|
/* terminate communication */
|
|
if (handle->_active && !handle->_terminated && handle->_term) {
|
|
log_info("we were active, send sending terminate packet");
|
|
if (p7_send_term(handle)) {
|
|
log_warn("couldn't send terminate packet, already disconnected?");
|
|
}
|
|
/* don't bother checking ack */
|
|
}
|
|
|
|
/* close stream */
|
|
(*handle->_stream->close)(handle->_stream->cookie);
|
|
|
|
/* free handle */
|
|
log_info("freeing the handle!");
|
|
if (handle->_wasalloc) free(handle);
|
|
}
|