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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
#include <stdio.h>
#include <stdlib.h>
#include "erl_driver.h"
static ErlDrvPort erlang_port;
static ErlDrvData control_start(ErlDrvPort, char*);
static void control_stop(ErlDrvData);
static void control_read(ErlDrvData, char*, int);
static int control_control(ErlDrvData, unsigned int, char*, int, char**, int);
static ErlDrvEntry control_driver_entry =
{
NULL,
control_start,
control_stop,
control_read,
NULL,
NULL,
"control_drv",
NULL,
NULL,
control_control,
NULL,
NULL,
NULL
};
DRIVER_INIT(control_drv)
{
erlang_port = (ErlDrvPort)-1;
return &control_driver_entry;
}
static ErlDrvData control_start(ErlDrvPort port,char *buf)
{
if (erlang_port != (ErlDrvPort)-1)
return ERL_DRV_ERROR_GENERAL;
erlang_port = port;
return (ErlDrvData)port;
}
static void control_read(ErlDrvData port, char *buf, int count)
{
driver_output(erlang_port, buf, count);
}
static void control_stop(ErlDrvData port)
{
erlang_port = (ErlDrvPort)-1;
}
static int control_control(ErlDrvData port, unsigned command, char* buf, int count,
char** res, int res_size)
{
switch (command) {
case 'e':
if (count > res_size) {
*res = (char *) driver_alloc(count);
}
memcpy(*res, buf, count);
return count;
case 'b':
set_busy_port(erlang_port, buf[0]);
return 0;
case 'i':
driver_output(erlang_port, buf, count);
return 0;
default:
if (command < 256) {
return -1;
} else {
char* p = *res;
int i;
for (i = 3; i >= 0; i--) {
p[i] = command;
command >>= 8;
}
return 4;
}
}
}
|