aboutsummaryrefslogtreecommitdiffstats
path: root/NEWS
blob: 356ed2f8757e36a77509393c35b29ec24bd257f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
   ---   LCD4Linux News   ---



lcd4linux-0.98

- improved signal-handling: lcd4linux can be restarted by sending a SIGHUP

- lcd4linux uses syslog for messages/warnings etc.

- support for GPO's (general purpose outputs, e.g. to connect a LED)
  The MatroxOrbital Displays have one GPO, and you can connect up to eight
  LED's to the parallel port using two IC's (see README.HD44780.GPO)

- new delay loop for parallel port displays: uses either gettimeofday() or
  rdtsc (time stamp counter on newer processors). This delay needs no longer
  a calibration! The 'Delay'-entry in lcd4linux.conf has gone.

- new raster driver for PNG creation

- new curses-based text driver

- security: lcd4linux.conf must have the same user/group than the executable, 
  and must not me accesible by group and other (i.e. mode 0600). This is 
  necessary because lcd4linux.conf can contain usernames and passwords for 
  POP and IMAP queries.

- support for plugins: new token 'x1'..'x9' for externel programs

- new token 'ic' (ISDN connected/offline, mainly for a LED connected to a GPO)

- APM client: new tokens 'bp', 'bs', 'bd' (battery percentage, status and 
  duration)

- mail client: new tokens 'e1'..'e9' for counting emails in local mailboxes

- new configure-options '--with-drivers=<list>', so you can compile a minimal
  executable which contains only the drivers you need.

- seti@home client: new tokens 'hc' (% completed) and 'ht' (cpu time needed)

- simple web-server driver (see README.Webinterface)

- uses new (kernel 2.4) ppdev system to access parallel port via ioctl()

- mail suport for pop3 and imap4, token 'u1' ..'u9' show unseen mail
  (which is propably incorrect for normal mbox)

- added another verbose level (-vvv) for debugging socket traffic

- added nntp support for count of news/unread messages in subscribed NGs

- implemented time series bar '$t'
eight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/*
	en50221 encoder An implementation for libdvb
	an implementation for the en50221 transport layer

	Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)

	This program 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; either version 2.1 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 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
*/

#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <errno.h>
#include <libdvbapi/dvbca.h>
#include "en50221_app_utils.h"
#include "en50221_app_tags.h"
#include "en50221_stdcam.h"


struct en50221_stdcam_hlci {
	struct en50221_stdcam stdcam;

	int cafd;
	int slotnum;
	int initialised;
	struct en50221_app_send_functions sendfuncs;
};

static void en50221_stdcam_hlci_destroy(struct en50221_stdcam *stdcam, int closefd);
static enum en50221_stdcam_status en50221_stdcam_hlci_poll(struct en50221_stdcam *stdcam);
static int hlci_cam_added(struct en50221_stdcam_hlci *hlci);
static int hlci_send_data(void *arg, uint16_t session_number,
			  uint8_t * data, uint16_t data_length);
static int hlci_send_datav(void *arg, uint16_t session_number,
			   struct iovec *vector, int iov_count);




struct en50221_stdcam *en50221_stdcam_hlci_create(int cafd, int slotnum)
{
	// try and allocate space for the HLCI stdcam
	struct en50221_stdcam_hlci *hlci =
		malloc(sizeof(struct en50221_stdcam_hlci));
	if (hlci == NULL) {
		return NULL;
	}
	memset(hlci, 0, sizeof(struct en50221_stdcam_hlci));

	// create the sendfuncs
	hlci->sendfuncs.arg = hlci;
	hlci->sendfuncs.send_data = hlci_send_data;
	hlci->sendfuncs.send_datav = hlci_send_datav;

	// create the resources (NOTE: we just use fake session numbers here)
	hlci->stdcam.ai_resource = en50221_app_ai_create(&hlci->sendfuncs);
	hlci->stdcam.ai_session_number = 0;
	hlci->stdcam.ca_resource = en50221_app_ca_create(&hlci->sendfuncs);
	hlci->stdcam.ca_session_number = 1;
//      hlci->stdcam.mmi_resource = en50221_app_mmi_create(&hlci->sendfuncs);
	hlci->stdcam.mmi_session_number = -1;

	// done
	hlci->stdcam.destroy = en50221_stdcam_hlci_destroy;
	hlci->stdcam.poll = en50221_stdcam_hlci_poll;
	hlci->slotnum = slotnum;
	hlci->cafd = cafd;
	return &hlci->stdcam;
}

static void en50221_stdcam_hlci_destroy(struct en50221_stdcam *stdcam, int closefd)
{
	struct en50221_stdcam_hlci *hlci = (struct en50221_stdcam_hlci *) stdcam;

	if (hlci->stdcam.ai_resource)
		en50221_app_ai_destroy(hlci->stdcam.ai_resource);
	if (hlci->stdcam.ca_resource)
		en50221_app_ca_destroy(hlci->stdcam.ca_resource);
	if (hlci->stdcam.mmi_resource)
		en50221_app_mmi_destroy(hlci->stdcam.mmi_resource);

	if (closefd)
		close(hlci->cafd);

	free(hlci);
}

static enum en50221_stdcam_status en50221_stdcam_hlci_poll(struct en50221_stdcam *stdcam)
{
	struct en50221_stdcam_hlci *hlci = (struct en50221_stdcam_hlci *) stdcam;

	switch(dvbca_get_cam_state(hlci->cafd, hlci->slotnum)) {
	case DVBCA_CAMSTATE_MISSING:
		hlci->initialised = 0;
		break;

	case DVBCA_CAMSTATE_READY:
	case DVBCA_CAMSTATE_INITIALISING:
		if (!hlci->initialised)
			hlci_cam_added(hlci);
		break;
	}

	// delay to prevent busy loop
	usleep(10);

	if (!hlci->initialised) {
		return EN50221_STDCAM_CAM_NONE;
	}
	return EN50221_STDCAM_CAM_OK;
}



static int hlci_cam_added(struct en50221_stdcam_hlci *hlci)
{
	uint8_t buf[256];
	int size;

	// get application information
	if (en50221_app_ai_enquiry(hlci->stdcam.ai_resource, 0)) {
		return -EIO;
	}
	if ((size = dvbca_hlci_read(hlci->cafd, TAG_APP_INFO, buf, sizeof(buf))) < 0) {
		return size;
	}
	if (en50221_app_ai_message(hlci->stdcam.ai_resource, 0, 0, EN50221_APP_AI_RESOURCEID, buf, size)) {
		return -EIO;
	}

	// we forge a fake CA_INFO here so the main app works - since it will expect a CA_INFO
	// this will be replaced with a proper call (below) when the driver support is there
	buf[0] = TAG_CA_INFO >> 16;
	buf[1] = (uint8_t) (TAG_CA_INFO >> 8);
	buf[2] = (uint8_t) TAG_CA_INFO;
	buf[3] = 0;
	if (en50221_app_ca_message(hlci->stdcam.ca_resource, 0, 0, EN50221_APP_CA_RESOURCEID, buf, 4)) {
		return -EIO;
	}

	/*
	// get CA information
	   if (en50221_app_ca_info_enq(ca_resource, 0)) {
	   fprintf(stderr, "Failed to send CA INFO enquiry\n");
	   cafd = -1;
	   return -1;
	   }
	   if ((size = dvbca_hlci_read(cafd, TAG_CA_INFO, buf, sizeof(buf))) < 0) {
	   fprintf(stderr, "Failed to read CA INFO\n");
	   cafd = -1;
	   return -1;
	   }
	   if (en50221_app_ca_message(ca_resource, 0, 0, EN50221_APP_CA_RESOURCEID, buf, size)) {
	   fprintf(stderr, "Failed to parse CA INFO\n");
	   cafd = -1;
	   return -1;
	   }
	 */

	// done
	hlci->initialised = 1;
	return 0;
}

static int hlci_send_data(void *arg, uint16_t session_number,
			  uint8_t * data, uint16_t data_length)
{
	(void) session_number;
	struct en50221_stdcam_hlci *hlci = arg;

	return dvbca_hlci_write(hlci->cafd, data, data_length);
}

static int hlci_send_datav(void *arg, uint16_t session_number,
			   struct iovec *vector, int iov_count)
{
	(void) session_number;
	struct en50221_stdcam_hlci *hlci = arg;

	// calculate the total length of the data to send
	uint32_t data_size = 0;
	int i;
	for (i = 0; i < iov_count; i++) {
		data_size += vector[i].iov_len;
	}

	// allocate memory for it
	uint8_t *buf = malloc(data_size);
	if (buf == NULL) {
		return -1;
	}
	// merge the iovecs
	uint32_t pos = 0;
	for (i = 0; i < iov_count; i++) {
		memcpy(buf + pos, vector[i].iov_base, vector[i].iov_len);
		pos += vector[i].iov_len;
	}

	// sendit and cleanup
	int status = dvbca_hlci_write(hlci->cafd, buf, data_size);
	free(buf);
	return status;
}