Compare commits
2 Commits
cd5f9f7a12
...
089154cb17
Author | SHA1 | Date |
---|---|---|
Alexander Zhirov | 089154cb17 | |
Alexander Zhirov | ee679a128b |
|
@ -34,7 +34,14 @@
|
||||||
"mpl-args.h": "c",
|
"mpl-args.h": "c",
|
||||||
"*.in": "cpp",
|
"*.in": "cpp",
|
||||||
"signal.h": "c",
|
"signal.h": "c",
|
||||||
"stdio.h": "c"
|
"stdio.h": "c",
|
||||||
|
"getopt.h": "c",
|
||||||
|
"mpl-common.h": "c",
|
||||||
|
"cerrno": "c",
|
||||||
|
"string": "c",
|
||||||
|
"string_view": "c",
|
||||||
|
"regex.h": "c",
|
||||||
|
"dirent.h": "c"
|
||||||
},
|
},
|
||||||
"cmake.configureOnOpen": false
|
"cmake.configureOnOpen": false
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
cmake_minimum_required(VERSION 3.18.4)
|
cmake_minimum_required(VERSION 3.18.4)
|
||||||
project(mportlink)
|
project(mportlink)
|
||||||
|
|
||||||
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Os")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Os")
|
||||||
|
|
||||||
set(VERSION_MAJOR 0)
|
set(VERSION_MAJOR 0)
|
||||||
set(VERSION_MINOR 1)
|
set(VERSION_MINOR 1)
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* mpl-common.c
|
||||||
|
*
|
||||||
|
* by Alexander Zhirov (alexander@zhirov.kz)
|
||||||
|
* Telegram @alexanderzhirov
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mpl-common.h"
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
|
||||||
|
#define LOCKFILE "/run/lock/mportlink.lock"
|
||||||
|
|
||||||
|
static int mpl_create_dongle_dir()
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat(MPL_DONGLE_PATH, &st) == 0)
|
||||||
|
{
|
||||||
|
if (!S_ISDIR(st.st_mode))
|
||||||
|
{
|
||||||
|
MPLOG(LOG_WARNING, "%s exists and is not a directory", MPL_DONGLE_PATH);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mkdir(MPL_DONGLE_PATH, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
|
||||||
|
{
|
||||||
|
MPLOG(LOG_ERR, "unable to create a directory %s", MPL_DONGLE_PATH);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void static mpl_free(MPL *mpl)
|
||||||
|
{
|
||||||
|
if (mpl)
|
||||||
|
free(mpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
MPL *mpl_init(MPL_PARAMETERS *parameters)
|
||||||
|
{
|
||||||
|
MPL *mpl = (MPL *)calloc(1, sizeof(MPL));
|
||||||
|
|
||||||
|
if (!mpl)
|
||||||
|
{
|
||||||
|
MPLOG(LOG_ERR, "error getting the MPL structure");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mpl->parameters.check_device = parameters->check_device;
|
||||||
|
mpl->cancellable.signal = 0;
|
||||||
|
mpl->cancellable.exit = 0;
|
||||||
|
|
||||||
|
mpl->fd = open(LOCKFILE, O_CREAT | O_RDWR, 0644);
|
||||||
|
if (mpl->fd < 0)
|
||||||
|
{
|
||||||
|
MPLOG(LOG_ERR, "unable to create a lockfile");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = flock(mpl->fd, LOCK_EX | LOCK_NB);
|
||||||
|
if (rc || errno == EWOULDBLOCK)
|
||||||
|
{
|
||||||
|
MPLOG(LOG_ERR, "only one instance of %s is allowed", MPL_NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mpl_create_dongle_dir())
|
||||||
|
{
|
||||||
|
MPLOG(LOG_ERR, "%s will be stopped", MPL_NAME);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mpl_udev_init(&mpl->udev))
|
||||||
|
{
|
||||||
|
MPLOG(LOG_ERR, "%s will be stopped", MPL_NAME);
|
||||||
|
mpl_free(mpl);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
MPLOG(LOG_NOTICE, "starting the %s daemon", MPL_NAME);
|
||||||
|
|
||||||
|
return mpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mpl_stop(MPL *mpl)
|
||||||
|
{
|
||||||
|
mpl_udev_free(&mpl->udev);
|
||||||
|
|
||||||
|
if (mpl->cancellable.exit)
|
||||||
|
{
|
||||||
|
flock(mpl->fd, LOCK_UN);
|
||||||
|
MPLOG(LOG_NOTICE, "stopping the %s daemon", MPL_NAME);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MPLOG(LOG_NOTICE, "successful completion of the process %d", getpid());
|
||||||
|
|
||||||
|
mpl_free(mpl);
|
||||||
|
|
||||||
|
closelog();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mpl_loop(MPL *mpl)
|
||||||
|
{
|
||||||
|
if (mpl->parameters.check_device)
|
||||||
|
mpl_udev_check_devices(&mpl->udev);
|
||||||
|
|
||||||
|
mpl_udev_loop(&mpl->udev, &mpl->cancellable);
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* mpl-common.h
|
||||||
|
*
|
||||||
|
* by Alexander Zhirov (alexander@zhirov.kz)
|
||||||
|
* Telegram @alexanderzhirov
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MPL_COMMON_H_
|
||||||
|
#define MPL_COMMON_H_
|
||||||
|
|
||||||
|
#include "mpl-lib.h"
|
||||||
|
#include "mpl-udev.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int check_device;
|
||||||
|
} MPL_PARAMETERS;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
MPL_PARAMETERS parameters;
|
||||||
|
MPL_CANCELLABLE cancellable;
|
||||||
|
MPL_UDEV udev;
|
||||||
|
} MPL;
|
||||||
|
|
||||||
|
MPL *mpl_init(MPL_PARAMETERS *parameters);
|
||||||
|
void mpl_stop(MPL *mpl);
|
||||||
|
void mpl_loop(MPL *mpl);
|
||||||
|
|
||||||
|
#endif
|
163
src/mpl-core.c
163
src/mpl-core.c
|
@ -5,108 +5,83 @@
|
||||||
* Telegram @alexanderzhirov
|
* Telegram @alexanderzhirov
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "mpl-lib.h"
|
||||||
#include "mpl-core.h"
|
#include "mpl-core.h"
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <regex.h>
|
||||||
#include <sys/file.h>
|
#include <dirent.h>
|
||||||
#include <unistd.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#define LOCKFILE "/run/lock/mportlink.lock"
|
int device_path(const MPL_MODEM *modem)
|
||||||
#define DEV_PATH "/dev/"
|
|
||||||
#define DONGLE_PATH (DEV_PATH "dongle/")
|
|
||||||
|
|
||||||
static int mpl_create_dongle_dir()
|
|
||||||
{
|
{
|
||||||
struct stat st;
|
DIR *dir;
|
||||||
|
struct dirent *ent;
|
||||||
|
regex_t regex;
|
||||||
|
const char *pattern = "^ttyUSB[0-9]*$";
|
||||||
|
|
||||||
if (stat(DONGLE_PATH, &st) == 0)
|
int ret = regcomp(®ex, pattern, REG_EXTENDED);
|
||||||
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
if (!S_ISDIR(st.st_mode))
|
printf("Failed to compile regular expression\n");
|
||||||
{
|
|
||||||
MPLOG(LOG_WARNING, "%s exists and is not a directory", DONGLE_PATH);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mkdir(DONGLE_PATH, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
|
|
||||||
{
|
|
||||||
MPLOG(LOG_ERR, "unable to create a directory %s", DONGLE_PATH);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dir = opendir(modem->path);
|
||||||
|
if (dir == NULL)
|
||||||
|
{
|
||||||
|
printf("Failed to open directory: %s\n", modem->path);
|
||||||
|
regfree(®ex);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((ent = readdir(dir)) != NULL)
|
||||||
|
{
|
||||||
|
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regexec(®ex, ent->d_name, 0, NULL, 0);
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
printf("Found a file matching the pattern: %s\n", ent->d_name);
|
||||||
|
|
||||||
|
char *path = (char *)calloc(strlen(MPL_DEV_PATH) + strlen(ent->d_name) + 1, sizeof(char));
|
||||||
|
strcpy(path, MPL_DEV_PATH);
|
||||||
|
strcat(path, ent->d_name);
|
||||||
|
|
||||||
|
int fd = open(path, O_RDWR);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("Не удалось открыть USB устройство.\n");
|
||||||
|
free(path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *tty = ttyname(fd);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
if (tty != NULL)
|
||||||
|
{
|
||||||
|
printf("%s устройство tty: %s\n", modem->action ? "Добавлено" : "Удалено", tty);
|
||||||
|
|
||||||
|
// if (!num)
|
||||||
|
// print_imei(tty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Устройство tty не найдено\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ret != REG_NOMATCH)
|
||||||
|
{
|
||||||
|
printf("Failed to apply regular expression\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
regfree(®ex);
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void static mpl_free(MPL *mpl)
|
|
||||||
{
|
|
||||||
if (mpl)
|
|
||||||
free(mpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
MPL *mpl_init(MPL_PARAMETERS *parameters)
|
|
||||||
{
|
|
||||||
MPL *mpl = (MPL *)calloc(1, sizeof(MPL));
|
|
||||||
|
|
||||||
if (!mpl)
|
|
||||||
{
|
|
||||||
MPLOG(LOG_ERR, "error getting the MPL structure");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
mpl->parameters.check_device = parameters->check_device;
|
|
||||||
mpl->cancellable.signal = 0;
|
|
||||||
mpl->cancellable.exit = 0;
|
|
||||||
|
|
||||||
mpl->fd = open(LOCKFILE, O_CREAT | O_RDWR, 0644);
|
|
||||||
if (mpl->fd < 0)
|
|
||||||
{
|
|
||||||
MPLOG(LOG_ERR, "unable to create a lockfile");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int rc = flock(mpl->fd, LOCK_EX | LOCK_NB);
|
|
||||||
if (rc || errno == EWOULDBLOCK)
|
|
||||||
{
|
|
||||||
MPLOG(LOG_ERR, "only one instance of %s is allowed", MPL_NAME);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mpl_create_dongle_dir())
|
|
||||||
{
|
|
||||||
MPLOG(LOG_ERR, "%s will be stopped", MPL_NAME);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mpl_udev_init(&mpl->udev))
|
|
||||||
{
|
|
||||||
MPLOG(LOG_ERR, "%s will be stopped", MPL_NAME);
|
|
||||||
mpl_free(mpl);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
MPLOG(LOG_NOTICE, "starting the %s daemon", MPL_NAME);
|
|
||||||
|
|
||||||
return mpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mpl_stop(MPL *mpl)
|
|
||||||
{
|
|
||||||
mpl_udev_free(&mpl->udev);
|
|
||||||
|
|
||||||
flock(mpl->fd, LOCK_UN);
|
|
||||||
|
|
||||||
mpl_free(mpl);
|
|
||||||
|
|
||||||
if (mpl->cancellable.exit)
|
|
||||||
MPLOG(LOG_NOTICE, "stopping the %s daemon", MPL_NAME);
|
|
||||||
else
|
|
||||||
MPLOG(LOG_NOTICE, "successful completion of the process %d", getpid());
|
|
||||||
closelog();
|
|
||||||
}
|
|
||||||
|
|
||||||
void mpl_loop(MPL *mpl)
|
|
||||||
{
|
|
||||||
if (mpl->parameters.check_device)
|
|
||||||
mpl_udev_check_devices(&mpl->udev);
|
|
||||||
|
|
||||||
mpl_udev_loop(&mpl->udev, &mpl->cancellable);
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,24 +8,13 @@
|
||||||
#ifndef MPL_CORE_H_
|
#ifndef MPL_CORE_H_
|
||||||
#define MPL_CORE_H_
|
#define MPL_CORE_H_
|
||||||
|
|
||||||
#include "mpl-lib.h"
|
|
||||||
#include "mpl-udev.h"
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int check_device;
|
int port;
|
||||||
} MPL_PARAMETERS;
|
char *path;
|
||||||
|
int action;
|
||||||
|
} MPL_MODEM;
|
||||||
|
|
||||||
typedef struct
|
int device_path(const MPL_MODEM *modem);
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
MPL_PARAMETERS parameters;
|
|
||||||
MPL_CANCELLABLE cancellable;
|
|
||||||
MPL_UDEV udev;
|
|
||||||
} MPL;
|
|
||||||
|
|
||||||
MPL *mpl_init(MPL_PARAMETERS *parameters);
|
|
||||||
void mpl_stop(MPL *mpl);
|
|
||||||
void mpl_loop(MPL *mpl);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,3 +6,20 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mpl-lib.h"
|
#include "mpl-lib.h"
|
||||||
|
|
||||||
|
char *mpl_get_copy_string(const char *str)
|
||||||
|
{
|
||||||
|
int size = strlen(str);
|
||||||
|
char *copy = (char *)calloc(size + 1, sizeof(char));
|
||||||
|
|
||||||
|
if (!copy)
|
||||||
|
{
|
||||||
|
MPLOG(LOG_ERR, "error getting the string");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(copy, str);
|
||||||
|
copy[size] = '\0';
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
|
@ -14,8 +14,11 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#define MPL_NAME "mportlink"
|
#define MPL_NAME "mportlink"
|
||||||
|
#define MPL_DEV_PATH "/dev/"
|
||||||
|
#define MPL_DONGLE_PATH (MPL_DEV_PATH "dongle/")
|
||||||
|
|
||||||
#define MPLOG(PRIORITY, fmt, ...) do { \
|
#define MPLOG(PRIORITY, fmt, ...) do { \
|
||||||
char buf[256]; \
|
char buf[256]; \
|
||||||
|
@ -31,4 +34,6 @@ typedef struct
|
||||||
int exit;
|
int exit;
|
||||||
} MPL_CANCELLABLE;
|
} MPL_CANCELLABLE;
|
||||||
|
|
||||||
|
char *mpl_get_copy_string(const char *str);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
178
src/mpl-udev.c
178
src/mpl-udev.c
|
@ -6,10 +6,48 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mpl-udev.h"
|
#include "mpl-udev.h"
|
||||||
|
#include "mpl-core.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
void test(struct udev_device *dev)
|
||||||
|
{
|
||||||
|
const char *action = udev_device_get_action(dev);
|
||||||
|
// printf("action: %s\n", action);
|
||||||
|
// const char *devpath = udev_device_get_devpath(dev);
|
||||||
|
// printf("devpath: %s\n", devpath);
|
||||||
|
|
||||||
|
// const char *subsystem = udev_device_get_subsystem(dev);
|
||||||
|
// printf("subsystem: %s\n", subsystem);
|
||||||
|
|
||||||
|
const char *devtype = udev_device_get_devtype(dev);
|
||||||
|
// printf("devtype: %s\n", devtype);
|
||||||
|
|
||||||
|
const char *driver = udev_device_get_driver(dev);
|
||||||
|
// printf("driver: %s\n", driver);
|
||||||
|
|
||||||
|
// const char *sysattr_value = udev_device_get_sysattr_value(dev, "bInterfaceNumber");
|
||||||
|
// printf("Номер порта: %s\n", sysattr_value);
|
||||||
|
|
||||||
|
const char *syspath = udev_device_get_syspath(dev);
|
||||||
|
// printf("syspath: %s\n", syspath);
|
||||||
|
|
||||||
|
// const char *sysname = udev_device_get_sysname(dev);
|
||||||
|
// printf("sysname: %s\n", sysname);
|
||||||
|
|
||||||
|
// const char *sysnum = udev_device_get_sysnum(dev);
|
||||||
|
// printf("sysnum: %s\n", sysnum);
|
||||||
|
|
||||||
|
const char *devnode = udev_device_get_devnode(dev);
|
||||||
|
// printf("devnode: %s\n", devnode);
|
||||||
|
|
||||||
|
// int is_initialized = udev_device_get_is_initialized(dev);
|
||||||
|
// printf("is_initialized: %d\n", is_initialized);
|
||||||
|
|
||||||
|
printf("action: %s\tdevtype: %s\tdriver: %s\tsyspath: %s\tdevnode: %s\n", action, devtype, driver, syspath, devnode);
|
||||||
|
}
|
||||||
|
|
||||||
int mpl_udev_init(MPL_UDEV *udev)
|
int mpl_udev_init(MPL_UDEV *udev)
|
||||||
{
|
{
|
||||||
udev->context = udev_new();
|
udev->context = udev_new();
|
||||||
|
@ -41,12 +79,71 @@ int mpl_udev_init(MPL_UDEV *udev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// action: bind devtype: usb_interface driver: option syspath: /sys/devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3.3/3-3.3:1.1
|
||||||
|
// action: unbind devtype: usb_interface driver: (null) syspath: /sys/devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3.3/3-3.3:1.1
|
||||||
|
|
||||||
|
static int mpl_device_is_interface(struct udev_device *dev)
|
||||||
|
{
|
||||||
|
return strcmp(udev_device_get_devtype(dev), "usb_interface") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpl_device_is_modem(struct udev_device *dev)
|
||||||
|
{
|
||||||
|
const char *driver = udev_device_get_driver(dev);
|
||||||
|
const char *sysattr = udev_device_get_sysattr_value(dev, "bInterfaceNumber");
|
||||||
|
|
||||||
|
if (!driver || !sysattr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return mpl_device_is_interface(dev) && strcmp(driver, "option") == 0 && sysattr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpl_connect_modem(struct udev_device *dev)
|
||||||
|
{
|
||||||
|
const char *action = udev_device_get_property_value(dev, "ACTION");
|
||||||
|
|
||||||
|
return strcmp(action, "bind") == 0 && mpl_device_is_modem(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpl_disconnect_modem(struct udev_device *dev)
|
||||||
|
{
|
||||||
|
const char *action = udev_device_get_property_value(dev, "ACTION");
|
||||||
|
|
||||||
|
return strcmp(action, "unbind") == 0 && mpl_device_is_interface(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MPL_MODEM *mpl_get_modem_info(struct udev_device *dev)
|
||||||
|
{
|
||||||
|
MPL_MODEM *modem = (MPL_MODEM *)calloc(1, sizeof(MPL_MODEM));
|
||||||
|
|
||||||
|
if (modem == NULL)
|
||||||
|
{
|
||||||
|
MPLOG(LOG_ERR, "error creating modem");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
modem->port = atoi(udev_device_get_sysattr_value(dev, "bInterfaceNumber"));
|
||||||
|
modem->path = mpl_get_copy_string(udev_device_get_syspath(dev));
|
||||||
|
modem->action = strcmp(udev_device_get_property_value(dev, "ACTION"), "bind") == 0;
|
||||||
|
|
||||||
|
return modem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mpl_free_modem(MPL_MODEM *modem)
|
||||||
|
{
|
||||||
|
if (modem->path)
|
||||||
|
free(modem->path);
|
||||||
|
free(modem);
|
||||||
|
}
|
||||||
|
|
||||||
int mpl_udev_check_devices(MPL_UDEV *udev)
|
int mpl_udev_check_devices(MPL_UDEV *udev)
|
||||||
{
|
{
|
||||||
struct udev_device *dev;
|
struct udev_device *dev;
|
||||||
struct udev_enumerate *enumerate;
|
struct udev_enumerate *enumerate;
|
||||||
struct udev_list_entry *devices, *dev_list_entry;
|
struct udev_list_entry *devices, *dev_list_entry;
|
||||||
|
|
||||||
|
MPL_MODEM *modem = NULL;
|
||||||
|
|
||||||
enumerate = udev_enumerate_new(udev->context);
|
enumerate = udev_enumerate_new(udev->context);
|
||||||
|
|
||||||
if (enumerate == NULL)
|
if (enumerate == NULL)
|
||||||
|
@ -71,23 +168,14 @@ int mpl_udev_check_devices(MPL_UDEV *udev)
|
||||||
const char *syspath = udev_list_entry_get_name(dev_list_entry);
|
const char *syspath = udev_list_entry_get_name(dev_list_entry);
|
||||||
dev = udev_device_new_from_syspath(udev->context, syspath);
|
dev = udev_device_new_from_syspath(udev->context, syspath);
|
||||||
|
|
||||||
const char *devtype = udev_device_get_devtype(dev);
|
if (!mpl_device_is_modem(dev))
|
||||||
if (!(strcmp(devtype, "usb_interface") == 0))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const char *driver = udev_device_get_driver(dev);
|
modem = mpl_get_modem_info(dev);
|
||||||
if (!(strcmp(driver, "option") == 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *sysattr_value = udev_device_get_sysattr_value(dev, "bInterfaceNumber");
|
device_path(modem);
|
||||||
printf("Номер порта: %s\n", sysattr_value);
|
|
||||||
|
|
||||||
// int num = atoi(sysattr_value);
|
|
||||||
|
|
||||||
const char *devsyspath = udev_device_get_syspath(dev);
|
|
||||||
printf("syspath: %s\n", devsyspath);
|
|
||||||
// device_path(syspaths, num);
|
|
||||||
|
|
||||||
|
mpl_free_modem(modem);
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,12 +200,13 @@ void mpl_udev_free(MPL_UDEV *udev)
|
||||||
|
|
||||||
void mpl_udev_loop(MPL_UDEV *udev, MPL_CANCELLABLE *cancellable)
|
void mpl_udev_loop(MPL_UDEV *udev, MPL_CANCELLABLE *cancellable)
|
||||||
{
|
{
|
||||||
const char *path_to_device = NULL;
|
MPL_MODEM *modem = NULL;
|
||||||
int port_number = -1;
|
|
||||||
int status = -1;
|
int status = -1;
|
||||||
pid_t pid = -1;
|
pid_t pid = -1;
|
||||||
|
|
||||||
while (1)
|
int stop = 0;
|
||||||
|
|
||||||
|
while (!stop)
|
||||||
{
|
{
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
|
@ -135,46 +224,25 @@ void mpl_udev_loop(MPL_UDEV *udev, MPL_CANCELLABLE *cancellable)
|
||||||
struct udev_device *dev = udev_monitor_receive_device(udev->monitor);
|
struct udev_device *dev = udev_monitor_receive_device(udev->monitor);
|
||||||
if (dev)
|
if (dev)
|
||||||
{
|
{
|
||||||
const char *action = udev_device_get_property_value(dev, "ACTION");
|
// test(dev);
|
||||||
if (!(strcmp(action, "bind") == 0))
|
|
||||||
|
if (mpl_connect_modem(dev))
|
||||||
{
|
{
|
||||||
udev_device_unref(dev);
|
modem = mpl_get_modem_info(dev);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *devtype = udev_device_get_devtype(dev);
|
pid = fork();
|
||||||
if (!(strcmp(devtype, "usb_interface") == 0))
|
if (pid == 0)
|
||||||
|
{
|
||||||
|
stop = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wait(&status);
|
||||||
|
}
|
||||||
|
else if (mpl_disconnect_modem(dev))
|
||||||
{
|
{
|
||||||
udev_device_unref(dev);
|
// unmount ports
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *driver = udev_device_get_driver(dev);
|
|
||||||
if (!(strcmp(driver, "option") == 0))
|
|
||||||
{
|
|
||||||
udev_device_unref(dev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *sysattr_value = udev_device_get_sysattr_value(dev, "bInterfaceNumber");
|
|
||||||
if (sysattr_value == NULL)
|
|
||||||
{
|
|
||||||
udev_device_unref(dev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
port_number = atoi(sysattr_value);
|
|
||||||
path_to_device = udev_device_get_syspath(dev);
|
|
||||||
|
|
||||||
pid = fork();
|
|
||||||
if (pid == 0)
|
|
||||||
{
|
|
||||||
udev_device_unref(dev);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
wait(&status);
|
|
||||||
|
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,6 +252,8 @@ void mpl_udev_loop(MPL_UDEV *udev, MPL_CANCELLABLE *cancellable)
|
||||||
if (cancellable->exit)
|
if (cancellable->exit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sleep(5);
|
// printf("path: %s\t port: %d\t action: %d\n", modem->path, modem->port, modem->action);
|
||||||
printf("exit");
|
|
||||||
|
device_path(modem);
|
||||||
|
mpl_free_modem(modem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
* Telegram @alexanderzhirov
|
* Telegram @alexanderzhirov
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
|
||||||
|
|
||||||
#include "mpl.h"
|
#include "mpl.h"
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
static MPL *mpl;
|
static MPL *mpl;
|
||||||
|
|
||||||
|
|
Reference in New Issue