-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathztedialmanager.cc
158 lines (128 loc) · 4.21 KB
/
ztedialmanager.cc
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright: (C) 2016 ESIMTEK ALL RIGHTS RESERVED
// author: Yonghua Zheng
#include <signal.h>
#include <libudev.h>
#include <sys/wait.h>
#include "dispatchmanager.h"
#include "signalistener.h"
#include "log.h"
#include "ztedial.h"
#include "ztedialmanager.h"
#include "ztenetlink.h"
ZteDialManager::ZteDialManager()
{
DispatchManager::Instantiate();
scan_device();
}
ZteDialManager::~ZteDialManager()
{
DispatchManager::Dispose();
}
void ZteDialManager::scan_device()
{
struct udev *udev;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *dev_list_entry;
struct udev_device *dev, *parent, *interface;
/* Create the udev object */
udev = udev_new();
if (!udev) {
Log::Error("Can't create udev");
return;
}
/* Create a list of the devices in the 'tty' subsystem. */
enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate, "tty");
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
/* For each item enumrated, match the ZTE 4G LTE modem */
udev_list_entry_foreach(dev_list_entry, devices) {
const char *path;
path = udev_list_entry_get_name(dev_list_entry);
dev = udev_device_new_from_syspath(udev, path);
parent = udev_device_get_parent_with_subsystem_devtype(
dev,
"usb",
"usb_device");
if (parent) {
/* get idVendor/idProduct */
int idVendor = strtoul(udev_device_get_sysattr_value(parent, "idVendor"), 0, 16);
int idProduct = strtoul(udev_device_get_sysattr_value(parent, "idProduct"), 0, 16);
if (idVendor != 0x19d2 && idProduct != 0x0199) {
udev_device_unref(dev);
continue;
}
}
interface = udev_device_get_parent_with_subsystem_devtype(
dev,
"usb",
"usb_interface");
if (interface) {
const char *intf =
udev_device_get_sysattr_value(interface, "interface");
if (!strncmp(intf, "USB-AT", 6)) {
char message[64];
snprintf(message, sizeof(message),
"ACTION=add, DEVNODE=%s",
udev_device_get_devnode(dev));
Log::Info("%s", message);
DispatchManager::Post(DispatchManager::main_id, message);
}
}
udev_device_unref(dev);
}
/* Free the enumerator object */
udev_enumerate_unref(enumerate);
udev_unref(udev);
}
int ZteDialManager::main_loop_run()
{
SignalListener* signaler;
ZteNetlink* netlink;
signaler = new SignalListener();
signaler->watch(SIGTERM);
signaler->watch(SIGINT);
signaler->watch(SIGHUP);
signaler->watch(SIGCHLD);
netlink = ZteNetlink::open();
netlink->start();
for (;;) {
char message[1024];
int n = DispatchManager::Get(DispatchManager::main_id, message, sizeof(message));
if (n < 0)
break;
if (!n)
continue;
char *p = message;
if (!strncmp(p, "ACTION=", 7)) {
p += 7;
if (!strncmp(p, "exit", 4))
break;
else if (!strncmp(p, "add", 3)) {
p = strstr(p + 3, "DEVNODE=");
if (!p) continue;
p += 8;
if (fork() == 0) {
// reset the signal table
signaler->clean();
// reinitialize dispatchmanager context
DispatchManager::Dispose();
DispatchManager::Instantiate();
// reinitialize signal handler
signaler->watch(SIGTERM);
signaler->watch(SIGINT);
signaler->watch(SIGHUP);
// now run the dialer
ZteDial::dial(p);
break;
}
} else if (!strncmp(p, "waitpid", 7)) {
int status;
while (waitpid(-1, &status, WNOHANG) > 0);
}
}
}
delete signaler;
delete netlink;
return 0;
}