view src/cs/riviera/rvt/rvt_keepalive.c @ 27:cb3f6fe694e1 default tip

README: document SE K2x0 addition
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 21 Dec 2023 21:44:43 +0000
parents 92470e5d0b9e
children
line wrap: on
line source

/*
 * This module is a FreeCalypso addition.  Here we implement the special
 * operation mode that is only used when a device that was originally
 * meant to be a phone handset is turned into a pseudo-modem with no UI,
 * requiring connection to a host computer running rvinterf for control.
 */

#ifdef PSEUDO_MODEM_KEEPALIVE

#include "nucleus.h"

#include "abb.h"

#include "rv/general.h"
#include "rv/rv_general.h"
#include "rvf/rvf_api.h"
#include "rvt/rvt_gen.h"
#include "rvt/rvt_def_i.h"
#include "rvt/rvt_env.h"
#include "rvt/rvt_env_i.h"
#include "rvm/rvm_use_id_list.h"

#include "uart/serialswitch.h"

#include <string.h>

volatile UINT8 rvt_keepalive_counter;

void rvt_keepalive_input(T_RVT_BUFFER p_msg, UINT16 msg_length)
{
	/* Checking for an invalid PDU. */
	if ((p_msg == NULL) || (msg_length != 1))
		return;

	/* Check for the correct opcode */
	if (*p_msg != 'A')
		return;

	/* good keepalive response from external host */
	rvt_keepalive_counter = 0;
}

void rvt_keepalive_register(void)
{
	T_RVT_USER_ID rvt_id;

	rvt_register_id("KEEPALIVE", &rvt_id, rvt_keepalive_input);
}

static void keepalive_send(UINT8 *buf, UINT32 size)
{
	UINT32 sent;

	for (sent = 0; sent < size; )
		sent += SER_tr_WriteNBytes(SER_LAYER_1, buf + sent,
					   size - sent);
}

#ifdef PSEUDO_MODEM_USB
static char poweroff_msg[] = "System: USB unplugged, powering off";
#else
static char poweroff_msg[] = "System: no keepalive response, powering off";
static UINT8 keepalive_msg[2] = {RVT_KEEPALIVE_HEADER, 'Q'};
#endif

static void keepalive_poweroff(void)
{
	UINT8 poweroff_msg_buf[50], *p;

	p = poweroff_msg_buf;
	*p++ = RVT_RV_HEADER;
	*p++ = 0;
	*p++ = 0;
	*p++ = 0;
	*p++ = 0;
	*p++ = RV_TRACE_LEVEL_ERROR;
	strcpy((char *)p, poweroff_msg);
	keepalive_send(poweroff_msg_buf, strlen(poweroff_msg) + 6);
	/* do it */
	ABB_Power_Off();
}

void rvt_keepalive_process(void)
{
	SYS_UWORD16 abb_status;

	abb_status = ABB_Read_Status();
	if (abb_status & CHGPRES) {
		rvt_keepalive_counter = 0;
		return;
	}

#ifdef PSEUDO_MODEM_USB
	keepalive_poweroff();
#else
	if (rvt_keepalive_counter >= 3)
		keepalive_poweroff();
	else {
		rvt_keepalive_counter++;
		keepalive_send(keepalive_msg, sizeof keepalive_msg);
	}
#endif
}

#endif