00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <string.h>
00026 #include <termios.h>
00027 #include <unistd.h>
00028 #include <curses.h>
00029 #include <fcntl.h>
00030
00031 #include "backend.h"
00032
00033 #ifndef HAVE_CFMAKERAW
00034 # define HAVE_CFMAKERAW 0
00035 #endif
00036
00037
00038 typedef enum
00039 {
00040 NAME = 0, WIDTH, HEIGHT, DEVICE, BAUDRATE
00041 }
00042 tag_e;
00043
00044 tag_e tag[] =
00045 {
00046 NAME, WIDTH, HEIGHT, DEVICE, BAUDRATE
00047 };
00048
00049 dict_pair tag_dict[] =
00050 {
00051 { "baudrate", &tag[BAUDRATE] },
00052 { "device", &tag[DEVICE] },
00053 { "height", &tag[HEIGHT] },
00054 { "name", &tag[NAME] },
00055 { "width", &tag[WIDTH] }
00056 };
00057
00058 dictionary tags =
00059 {
00060 tag_dict, 5
00061 };
00062
00063
00064
00065 typedef struct
00066 {
00067 int opened;
00068 void *dev_handle;
00069 int (*send_func) (void *, const char *, size_t);
00070 void (*close_func) (void *);
00071 }
00072 bck_handle;
00073
00074 typedef struct
00075 {
00076 WINDOW *cont;
00077 WINDOW *border;
00078 }
00079 cursd;
00080
00081
00082
00083
00084
00085
00086
00087
00088 static int
00089 _send_serial (void *h, const char *data, size_t len)
00090 {
00091 size_t result;
00092
00093 while (len > 0)
00094 {
00095 result = write (*(int *) h, data, len);
00096 if (result < 0)
00097 return 0;
00098
00099 len -= result;
00100 }
00101 return 1;
00102 }
00103
00104
00105 static void
00106 _close_serial (void *h)
00107 {
00108 close (*(int *) h);
00109 }
00110
00111
00112 static void
00113 _open_serial (bck_handle * h, xml_node *config)
00114 {
00115 struct termios portset;
00116 const char* baud = 0;
00117 const char* device = "/dev/ttyS0";
00118 xml_node *node;
00119 int _baudrate;
00120 int fd;
00121
00122 node = xmlt_find (config, 0, DEVICE);
00123 if (node)
00124 device = xmlt_get_first_cdata (node);
00125
00126 node = xmlt_find (config, 0, BAUDRATE);
00127 if (node)
00128 baud = xmlt_get_first_cdata (node);
00129
00130 fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY);
00131 if (fd < 0)
00132 return;
00133
00134 if (baud == 0)
00135 _baudrate = B9600;
00136 else
00137 {
00138 switch (atoi (baud))
00139 {
00140 case 600:
00141 _baudrate = B600;
00142 break;
00143 case 1200:
00144 _baudrate = B1200;
00145 break;
00146 case 1800:
00147 _baudrate = B1800;
00148 break;
00149 case 2400:
00150 _baudrate = B2400;
00151 break;
00152 case 4800:
00153 _baudrate = B4800;
00154 break;
00155 case 9600:
00156 _baudrate = B9600;
00157 break;
00158 case 19200:
00159 _baudrate = B19200;
00160 break;
00161 case 38400:
00162 _baudrate = B38400;
00163 break;
00164 case 57600:
00165 _baudrate = B57600;
00166 break;
00167 case 115200:
00168 _baudrate = B115200;
00169 break;
00170 case 230400:
00171 _baudrate = B230400;
00172 break;
00173 default:
00174 _baudrate = B9600;
00175 break;
00176 }
00177 }
00178
00179
00180 tcgetattr (fd, &portset);
00181
00182 #if HAVE_CFMAKERAW
00183 cfmakeraw (&portset);
00184 #else
00185 portset.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
00186 | INLCR | IGNCR | ICRNL | IXON);
00187 portset.c_oflag &= ~OPOST;
00188 portset.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
00189 portset.c_cflag &= ~(CSIZE | PARENB);
00190 portset.c_cflag |= CS8 | CREAD | CLOCAL;
00191 #endif
00192
00193
00194 cfsetospeed (&portset, _baudrate);
00195 cfsetispeed (&portset, B0);
00196 tcsetattr (fd, TCSANOW, &portset);
00197
00198 h->dev_handle = 0;
00199 h->send_func = _send_serial;
00200 h->close_func = _close_serial;
00201 h->dev_handle = malloc (sizeof (int));
00202 if (h->dev_handle == 0)
00203 exit (EXIT_FAILURE);
00204
00205 *((int *) h->dev_handle) = fd;
00206 h->opened = 1;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 static int
00218 _send_curses (void *h, const char *data, size_t len)
00219 {
00220 cursd *x = h;
00221
00222 waddnstr (x->cont, data, len);
00223 touchwin (x->cont);
00224 wrefresh (x->cont);
00225
00226 return 1;
00227 }
00228
00229
00230 static void
00231 _close_curses (void *h)
00232 {
00233 cursd *x = h;
00234
00235 delwin (x->border);
00236 delwin (x->cont);
00237 endwin ();
00238 curs_set (1);
00239 }
00240
00241
00242 static void
00243 _open_curses (bck_handle *h, xml_node *config)
00244 {
00245 cursd *x;
00246 int width = 20;
00247 int height = 4;
00248 int wx;
00249 int wy;
00250 const char *num;
00251 xml_node *node;
00252
00253 num = 0;
00254 node = xmlt_find (config, 0, WIDTH);
00255 if (node)
00256 num = xmlt_get_first_cdata (node);
00257
00258 if (num)
00259 width = atoi (num);
00260
00261 num = 0;
00262 node = xmlt_find (config, 0, HEIGHT);
00263 if (node)
00264 num = xmlt_get_first_cdata (node);
00265
00266 if (num)
00267 height = atoi (num);
00268
00269 x = malloc (sizeof (cursd));
00270 if (x == 0)
00271 exit (EXIT_FAILURE);
00272
00273 if (initscr () == 0)
00274 return;
00275
00276 wy = 12 - (height / 2);
00277 wx = 40 - (width / 2);
00278 x->cont = newwin (height, width, wy, wx);
00279 x->border = newwin (height + 2, width + 4, wy - 1, wx - 2);
00280
00281 if ( x->cont == 0
00282 || x->border == 0
00283 || nonl() == ERR
00284 || noecho() == ERR
00285 || curs_set (0) == ERR)
00286 {
00287 free (x);
00288 endwin ();
00289 return;
00290 }
00291
00292 box (x->border, 0, 0);
00293 scrollok (x->cont, 0);
00294 touchwin (x->border);
00295 wrefresh (x->border);
00296
00297 h->dev_handle = x;
00298 h->send_func = _send_curses;
00299 h->close_func = _close_curses;
00300 h->opened = 1;
00301 }
00302
00303
00304
00305 void *
00306 backend_create_handle (xml_node *config, const char* type)
00307 {
00308 bck_handle *h = malloc (sizeof (bck_handle));
00309
00310 if (h == 0)
00311 exit (EXIT_FAILURE);
00312
00313 if (type == 0)
00314 return 0;
00315
00316 h->opened = 0;
00317 h->dev_handle = 0;
00318
00319 xmlt_rescan_document (config, &tags, 0);
00320
00321 if (!strcmp ("serial", type))
00322 _open_serial (h, config);
00323
00324 else if (!strcmp ("curses", type))
00325 _open_curses (h, config);
00326
00327 return (void *) h;
00328 }
00329
00330
00331 int
00332 backend_send (void *handle, const char *data, size_t len)
00333 {
00334 bck_handle *h = (bck_handle *) handle;
00335
00336 if (!h->opened)
00337 return -1;
00338
00339 return h->send_func (h->dev_handle, data, len);
00340 }
00341
00342
00343 void
00344 backend_free_handle (void *handle)
00345 {
00346 bck_handle *h = (bck_handle *) handle;
00347
00348 if (h->opened)
00349 h->close_func (h->dev_handle);
00350
00351 free (h->dev_handle);
00352 free (h);
00353 }