Страницы

Поиск по вопросам

Показаны сообщения с ярлыком модемы. Показать все сообщения
Показаны сообщения с ярлыком модемы. Показать все сообщения

вторник, 24 декабря 2019 г.

Раздать интернет

#linux #iptables #lan #route #модемы


Почему

$ ping ya.ru
ping: unknown host ya.ru

Комп1 (принимающий инет)

$ ifconfig wlan0
wlan0     Link encap:Ethernet  HWaddr b8:03:05:c9:3e:c5  
          inet addr:192.168.0.2  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::ba03:5ff:fec9:3ec5/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:33086 errors:0 dropped:0 overruns:0 frame:0
          TX packets:62823 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2797459 (2.7 MB)  TX bytes:90723494 (90.7 MB)

и так делал


$ ip route
default via 192.168.0.2 dev wlan0  scope link  metric 100 
192.168.0.0/24 dev wlan0  proto kernel  scope link  src 192.168.0.2  metric 9

и так делал

$ ip route
default via 192.168.0.1 dev wlan0  scope link  metric 100 
192.168.0.0/24 dev wlan0  proto kernel  scope link  src 192.168.0.2  metric 9

$ sudo iptables-save
:пусто



$ nslookup ya.ru
;; connection timed out; no servers could be reached

$ ping 8.8.8.8
connect: Network is unreachable



Комп2 (раздающий 3g)

$ ifconfig -a
eth0      Link encap:Ethernet  HWaddr b8:88:e3:67:d4:45  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:5976 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5976 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:547759 (547.7 KB)  TX bytes:547759 (547.7 KB)

ppp0      Link encap:Point-to-Point Protocol  
          inet addr:10.225.20.196  P-t-P:10.64.64.64  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:14699 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13627 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3 
          RX bytes:11287729 (11.2 MB)  TX bytes:2950024 (2.9 MB)

wlan0     Link encap:Ethernet  HWaddr 50:b7:c3:2a:68:31  
          inet addr:192.168.0.1  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::52b7:c3ff:fe2a:6831/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1000 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1021 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:148348 (148.3 KB)  TX bytes:108966 (108.9 KB)

wwan0     Link encap:Ethernet  HWaddr 58:2c:80:13:92:63  
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


$ ip route
default via 10.64.64.64 dev ppp0  metric 100 
10.64.64.64 dev ppp0  proto kernel  scope link  src 10.225.20.196 
192.168.0.0/24 dev wlan0  proto kernel  scope link  src 192.168.0.1  metric 9 

net.ipv4.ip_forward = 1

Даже после команды :

$ sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -d 10.0.0.0/24 -o ppp0 -j
MASQUERADE 

в iptables пусто

$ sudo iptables -L -v -n --line
Chain INPUT (policy ACCEPT 11498 packets, 8572K bytes)
num   pkts bytes target     prot opt in     out     source               destination
        

Chain FORWARD (policy ACCEPT 2 packets, 112 bytes)
num   pkts bytes target     prot opt in     out     source               destination
        

Chain OUTPUT (policy ACCEPT 11183 packets, 2394K bytes)
num   pkts bytes target     prot opt in     out     source               destination     

$ sudo iptables-save
# Generated by iptables-save v1.4.21 on Fri Aug 12 21:04:53 2016
*nat
:PREROUTING ACCEPT [437:43281]
:INPUT ACCEPT [389:28232]
:OUTPUT ACCEPT [1207:218579]
:POSTROUTING ACCEPT [66:9831]
-A POSTROUTING -o ppp0 -j MASQUERADE
COMMIT
# Completed on Fri Aug 12 21:04:53 2016
# Generated by iptables-save v1.4.21 on Fri Aug 12 21:04:53 2016
*filter
:INPUT ACCEPT [29340:31886316]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [21601:3071749]
-A FORWARD -s 192.168.0.0/24 -i wlan0 -o ppp0 -j ACCEPT
-A FORWARD -d 192.168.0.0/24 -i ppp0 -o wlan0 -j ACCEPT
COMMIT
# Completed on Fri Aug 12 21:04:53 2016

$ nslookup ya.ru
Server:     127.0.1.1
Address:    127.0.1.1#53

Non-authoritative answer:
Name:   ya.ru
Address: 93.158.134.3
Name:   ya.ru
Address: 213.180.193.3
Name:   ya.ru
Address: 213.180.204.3

Сделал :


iptables -F 
iptables -X
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
iptables -A FORWARD -i wlan0 -o ppp0 -s 192.168.0.0/24 -j ACCEPT
iptables -A FORWARD -i ppp0 -o wlan0 -d 192.168.0.0/24 -j ACCEPT


Получил

$ sudo iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 72 packets, 4357 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 65 packets, 3965 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 88 packets, 13008 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 5 packets, 890 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   90 12510 MASQUERADE  all  --  *      ppp0    0.0.0.0/0            0.0.0.0/0

Но маскарад так и не работает.



В итоге на комп2 есть инет и пингуется комп1. А на комп1 нет инета,хотя и пингуется
комп2. Почему нет интернета ?(
    


Ответы

Ответ 1



так как в вопросе не упомянут файл /etc/resolv.conf, скорее всего, в нём и дело. в этом файле сохраняется информация, необходимая системе для преобразования доменных имён в ip-адреса (и обратно). как минимум в нём должна присутствовать строка вида: nameserver ip-адрес где ip-адрес — это адрес dns-сервера (сервера имён), который, собственно, и выполнит (при обращении к нему со стороны вашей системы) упомянутое выше преобразование (например, ya.ru → 93.158.134.3). чем «ближе» находится сервер имён, тем быстрее будет получен от него ответ. вы можете взять адрес из аналогичного файла со второго компьютера. или воспользоваться каким-нибудь публичным: 8.8.8.8, 8.8.4.4 (поддерживаются компанией google) 77.88.8.8, 77.88.8.1 (поддерживаются компанией yandex)

Ответ 2



На обоих компах прописал в файл /etc/resolv.conf nameserver 8.8.8.8 Спасибо @alexander-barakin Сделал на компе2(с 3g инетом): iptables -F iptables -X iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE iptables -A FORWARD -i wlan0 -o ppp0 -s 192.168.0.0/24 -j ACCEPT iptables -A FORWARD -i ppp0 -o wlan0 -d 192.168.0.0/24 -j ACCEPT Спасибо @nobody И заработало. Всем спасибо!)

суббота, 7 декабря 2019 г.

systemd/udev: запуск демона при подключении модема и остановка демона при отсоединении модема

#linux #модемы #systemd


Возможно ли в systemd/udev реализовать так, чтобы при появлении в системе модема
(/dev/ttyACM%i) запускался демон modem@%i.service, и чтобы при отключении модема демон
останавливался?

Готовый полный универсальный рабочий рецепт.

/etc/ppp/peers/modem

460800
defaultroute
usepeerdns
crtscts
lock
noauth
local
persist
modem
nopcomp
novjccomp
nobsdcomp
nodeflate
noaccomp
ipcp-accept-local
ipcp-accept-remote
noipdefault
connect "/usr/sbin/chat -t10 -f /etc/ppp/chatscripts/modem.chat"


/etc/ppp/chatscripts/modem.chat

В поле точки доступа "internet.mts.ru" или подставьте точку доступа своего провайдера
или оставьте такой, если у вас российский МТС. Большинство провайдеров игнорируют это
поле, и его вообще можно не указывать, но МТС её требует и без неё не соединяет.

ABORT 'BUSY'
ABORT 'NO CARRIER'
ABORT 'VOICE'
ABORT 'NO DIALTONE'
ABORT 'NO DIAL TONE'
ABORT 'NO ANSWER'
ABORT 'DELAYED'
REPORT CONNECT
TIMEOUT 5
'' 'ATQ0'
'OK-AT-OK' 'ATZ'
TIMEOUT 3
'OK-AT-OK' 'ATI'
'OK' 'ATZ'
'OK' 'ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0'
'OK' 'AT\^SYSCFG=2,2,3fffffff,0,1'
'OK-AT-OK' 'AT+CGDCONT=1,"IP","internet.mts.ru"'
'OK' 'ATDT*99#'
CONNECT


/usr/lib/systemd/system/modem@.service

[Unit]
Description=Modem /dev/ttyACM%i
BindsTo=dev-ttyACM%i.device
After=dev-ttyACM%i.device
Before=network.target
Wants=network.target

[Service]
ExecStart=/usr/sbin/pppd call modem /dev/ttyACM%i

[Install]
WantedBy=multi-user.target


/etc/udev/rules.d/90-modem.rules

KERNEL=="ttyACM[0-9]*", TAG+="systemd", ENV{SYSTEMD_WANTS}="modem@%n.service"


Затем перезагрузить конфигурацию systemd.

sudo systemctl daemon-reload

И теперь достаточно просто подключить любой телефон, кроме огрызка, с любым оператором
в режим не накопителя. (Nokia suite, Телефон, Модем, Синхронизация и т.д.)

Ну, конечно же, желательно убедиться, что у вас определяется модем и его файл устройства,
как у меня, /dev/ttyACM0 и udev на него ссылается как dev-ttyACM0.device,  а не /dev/ttyUSB0
и dev-ttyUSB0.device или как-то иначе.
Цифру, обозначающую порядковый номер устройства (0) в демоне systemd заменяем на
%i, а в правилах udev на %n. Это даёт возможность не привязывать демон и правила только
к одному модему, а работать с неограниченным количеством модемов и корректно управлять
каждым модемом отдельно друг от друга.

systemctl list-units -tdevice -a | grep dev-tty

Телефон теперь всегда подключается к интернету при подключении к компьютеру, даже
если компьютер успешно подключён через ethernet или Wi-Fi к интернету. Правда, в этом
случае, когда в системе поднят (ifup) хоть 1 интерфейс, трафик идёт через него, а с
модемом лишь устанавливает соединение, но передачи данных не происходит.

Чтобы отключить автодозвон при подключении модема нужно просто  замаскировать демон
sudo systemctl mask modem@0.service, а потом, когда понадобится модем размаскировать
sudo systemctl unmask modem@0.service
0 - это порядковый номер модема, если у вас их несколько, то можно отключить ненужные
или отключить все.

И самое не приятное, если ethernet и/или Wi-Fi подняты (ifup), то трафик не будет
идти через модем, пока все интерфейсы не будут опущены (ifdown) даже если к ним не
подключен кабель или нет выхода в интернет. Но это уже особенность модемной маршрутизации.
    


Ответы

Ответ 1



Правильнее будет, чтобы udev запускал/останавливал systemd.service — это его работа. my.service [Unit] Description=Modem ppp0 <--> /dev/ttyACM0 BindsTo=dev-ttyACM0.device After=dev-ttyACM0.device Before=network.target Wants=network.target [Service] ExecStart=/usr/sbin/pppd call modem ExecStop=комманда на стоп KillMode=none Type=oneshot RemainAfterExit=yes [Install] WantedBy=multi-user.target Список всех устройств, но со своим ты уже разобрался: systemctl list-units --all --full | grep ".device" 90-my.rules в папку /etc/udev/rules.d/ KERNEL=="ttyACM*", ATTRS{serial}=="<СЕРИЙНИК>", TAG+="systemd", ENV{SYSTEMD_WANTS}="my.service" Можно добавить SYMLINK=="gsmmodem", тогда появится симлинк /dev/gsmmodem. А ATTR{serial} или подобные нужны, чтобы не спутать разные устройства. Получить серийник и прочие аттрибуты: udevadm info -a -n /dev/ttyACM* UPD Можно сделать так, чтобы из KERNEL=="ttyACM*" передавался номер устройства (цифра под звёздочкой) в сервис, которая бы потом дополняла бы строку запуска? 2.a Или будет всё же проще и лучше написать 2 демона (modem0.service и modem1.service) для ACM0 и ACM1? Для этого тебе нужен не просто сервис, а шаблонный сервис. Для этого переименуй my.service в my@.service и запускать их мы будем как my@ttyACM0.service и my@ttyACM1.service, тогда внутри файла тебе будут доступны такие переменные как %i %I (которые и будут именем сервиса, тот что после @). Меняешь все упоминания ttyACMX на %I и наслаждаешься =) Внутри udev доступны операторы %k and %n, это имя и номер соответственно (ты просил именно %k). Соответственно, исправляешь ENV{SYSTEMD_WANTS}="my@%k.service" и будет стартовать сервис my@ttyACM0.service. По поводу отключения. Тут сложнее, потому что когда устройство отключается, то его параметры становятся недоступны и уже сложно понять что же было отключено, можешь запустить udevadm monitor --environment --udev и выдернуть устройство, должен увидеть что-то типа #######REMOVE####### monitor will print the received events for: UDEV - the event which udev sends out after rule processing UDEV [21800.789239] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input75/mouse1 (input) ACTION=remove DEVLINKS=/dev/input/by-id/usb-Logitech_USB_Receiver-mouse /dev/input/by-path/pci-0000:00:1d.0-usb-0:1.3:1.0-mouse DEVNAME=/dev/input/mouse1 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input75/mouse1 ID_BUS=usb ID_INPUT=1 ID_INPUT_MOUSE=1 ID_MODEL=USB_Receiver ID_MODEL_ENC=USB\x20Receiver ID_MODEL_ID=c51a ID_PATH=pci-0000:00:1d.0-usb-0:1.3:1.0 ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_3_1_0 ID_REVISION=4100 ID_SERIAL=Logitech_USB_Receiver ID_TYPE=hid ID_USB_DRIVER=usbhid ID_USB_INTERFACES=:030102:030000: ID_USB_INTERFACE_NUM=00 ID_VENDOR=Logitech ID_VENDOR_ENC=Logitech ID_VENDOR_ID=046d MAJOR=13 MINOR=33 SEQNUM=3178 SUBSYSTEM=input UDEV_LOG=3 USEC_INITIALIZED=21797014959 UDEV [21800.792866] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input75/event6 (input) ACTION=remove DEVLINKS=/dev/input/by-id/usb-Logitech_USB_Receiver-event-mouse /dev/input/by-path/pci-0000:00:1d.0-usb-0:1.3:1.0-event-mouse DEVNAME=/dev/input/event6 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input75/event6 ID_BUS=usb ID_INPUT=1 ID_INPUT_MOUSE=1 ID_MODEL=USB_Receiver ID_MODEL_ENC=USB\x20Receiver ID_MODEL_ID=c51a ID_PATH=pci-0000:00:1d.0-usb-0:1.3:1.0 ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_3_1_0 ID_REVISION=4100 ID_SERIAL=Logitech_USB_Receiver ID_TYPE=hid ID_USB_DRIVER=usbhid ID_USB_INTERFACES=:030102:030000: ID_USB_INTERFACE_NUM=00 ID_VENDOR=Logitech ID_VENDOR_ENC=Logitech ID_VENDOR_ID=046d MAJOR=13 MINOR=70 SEQNUM=3179 SUBSYSTEM=input UDEV_LOG=3 USEC_INITIALIZED=21797013896 UDEV [21800.797061] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input75 (input) ACTION=remove DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input75 EV=17 ID_BUS=usb ID_INPUT=1 ID_INPUT_MOUSE=1 ID_MODEL=USB_Receiver ID_MODEL_ENC=USB\x20Receiver ID_MODEL_ID=c51a ID_PATH=pci-0000:00:1d.0-usb-0:1.3:1.0 ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_3_1_0 ID_REVISION=4100 ID_SERIAL=Logitech_USB_Receiver ID_TYPE=hid ID_USB_DRIVER=usbhid ID_USB_INTERFACES=:030102:030000: ID_USB_INTERFACE_NUM=00 ID_VENDOR=Logitech ID_VENDOR_ENC=Logitech ID_VENDOR_ID=046d KEY=ffff0000 0 0 0 0 0 0 0 0 MODALIAS=input:b0003v046DpC51Ae0111-e0,1,2,4,k110,111,112,113,114,115,116,117,118,119,11A,11B,11C,11D,11E,11F,r0,1,6,8,am4,lsfw MSC=10 NAME="Logitech USB Receiver" PHYS="usb-0000:00:1d.0-1.3/input0" PRODUCT=3/46d/c51a/111 PROP=0 REL=143 SEQNUM=3180 SUBSYSTEM=input UDEV_LOG=3 UNIQ="" USEC_INITIALIZED=21796479085 UDEV [21800.797132] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/0003:046D:C51A.004D/hidraw/hidraw2 (hidraw) ACTION=remove DEVNAME=/dev/hidraw2 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/0003:046D:C51A.004D/hidraw/hidraw2 MAJOR=251 MINOR=2 SEQNUM=3181 SUBSYSTEM=hidraw UDEV_LOG=3 USEC_INITIALIZED=21800796369 UDEV [21800.797172] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/0003:046D:C51A.004D (hid) ACTION=remove DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/0003:046D:C51A.004D HID_ID=0003:0000046D:0000C51A HID_NAME=Logitech USB Receiver HID_PHYS=usb-0000:00:1d.0-1.3/input0 MODALIAS=hid:b0003g0001v0000046Dp0000C51A SEQNUM=3182 SUBSYSTEM=hid UDEV_LOG=3 USEC_INITIALIZED=21800796501 UDEV [21800.798537] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0 (usb) ACTION=remove DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0 DEVTYPE=usb_interface INTERFACE=3/1/2 MODALIAS=usb:v046DpC51Ad4100dc00dsc00dp00ic03isc01ip02in00 PRODUCT=46d/c51a/4100 SEQNUM=3183 SUBSYSTEM=usb TYPE=0/0/0 UDEV_LOG=3 USEC_INITIALIZED=21800796538 UDEV [21800.814181] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/input/input76/event7 (input) ACTION=remove DEVLINKS=/dev/input/by-id/usb-Logitech_USB_Receiver-event-if01 /dev/input/by-path/pci-0000:00:1d.0-usb-0:1.3:1.1-event DEVNAME=/dev/input/event7 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/input/input76/event7 ID_BUS=usb ID_INPUT=1 ID_INPUT_KEY=1 ID_MODEL=USB_Receiver ID_MODEL_ENC=USB\x20Receiver ID_MODEL_ID=c51a ID_PATH=pci-0000:00:1d.0-usb-0:1.3:1.1 ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_3_1_1 ID_REVISION=4100 ID_SERIAL=Logitech_USB_Receiver ID_TYPE=hid ID_USB_DRIVER=usbhid ID_USB_INTERFACES=:030102:030000: ID_USB_INTERFACE_NUM=01 ID_VENDOR=Logitech ID_VENDOR_ENC=Logitech ID_VENDOR_ID=046d MAJOR=13 MINOR=71 SEQNUM=3184 SUBSYSTEM=input UDEV_LOG=3 USEC_INITIALIZED=21797013933 XKBLAYOUT=de XKBMODEL=pc105 UDEV [21800.816765] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/input/input76 (input) ABS=1 0 ACTION=remove DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/input/input76 EV=1f ID_BUS=usb ID_INPUT=1 ID_INPUT_KEY=1 ID_MODEL=USB_Receiver ID_MODEL_ENC=USB\x20Receiver ID_MODEL_ID=c51a ID_PATH=pci-0000:00:1d.0-usb-0:1.3:1.1 ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_3_1_1 ID_REVISION=4100 ID_SERIAL=Logitech_USB_Receiver ID_TYPE=hid ID_USB_DRIVER=usbhid ID_USB_INTERFACES=:030102:030000: ID_USB_INTERFACE_NUM=01 ID_VENDOR=Logitech ID_VENDOR_ENC=Logitech ID_VENDOR_ID=046d KEY=4837fff 72ff32d bf544446 0 0 1 20f90 8b17c000 677bfa d9415fed 9ed680 4400 0 10000002 MODALIAS=input:b0003v046DpC51Ae0111-e0,1,2,3,4,k71,72,73,74,77,80,82,83,85,86,87,88,89,8A,8B,8C,8E,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7,A8,A9,AB,AC,AD,AE,B0,B1,B2,B5,B6,CE,CF,D0,D1,D2,D4,D8,D9,DB,DF,E4,E7,E8,E9,EA,EB,F1,100,161,162,166,16A,16E,172,174,176,178,179,17A,17B,17C,17D,17F,180,182,183,185,188,189,18C,18D,18E,18F,190,191,192,193,195,198,199,19A,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA,1AB,1AC,1AD,1AE,1B0,1B1,1B7,1BA,r6,a20,m4,lsfw MSC=10 NAME="Logitech USB Receiver" PHYS="usb-0000:00:1d.0-1.3/input1" PRODUCT=3/46d/c51a/111 PROP=0 REL=40 SEQNUM=3185 SUBSYSTEM=input UDEV_LOG=3 UNIQ="" USEC_INITIALIZED=21796482192 UDEV [21800.817249] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/usbmisc/hiddev1 (usbmisc) ACTION=remove DEVNAME=/dev/usb/hiddev1 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/usbmisc/hiddev1 MAJOR=180 MINOR=1 SEQNUM=3186 SUBSYSTEM=usbmisc UDEV_LOG=3 USEC_INITIALIZED=21800816392 UDEV [21800.818490] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/0003:046D:C51A.004E/hidraw/hidraw3 (hidraw) ACTION=remove DEVNAME=/dev/hidraw3 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/0003:046D:C51A.004E/hidraw/hidraw3 MAJOR=251 MINOR=3 SEQNUM=3187 SUBSYSTEM=hidraw UDEV_LOG=3 USEC_INITIALIZED=21800816472 UDEV [21800.818536] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/0003:046D:C51A.004E (hid) ACTION=remove DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/0003:046D:C51A.004E HID_ID=0003:0000046D:0000C51A HID_NAME=Logitech USB Receiver HID_PHYS=usb-0000:00:1d.0-1.3/input1 MODALIAS=hid:b0003g0001v0000046Dp0000C51A SEQNUM=3188 SUBSYSTEM=hid UDEV_LOG=3 USEC_INITIALIZED=21800816908 UDEV [21800.818580] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1 (usb) ACTION=remove DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1 DEVTYPE=usb_interface INTERFACE=3/0/0 MODALIAS=usb:v046DpC51Ad4100dc00dsc00dp00ic03isc00ip00in01 PRODUCT=46d/c51a/4100 SEQNUM=3189 SUBSYSTEM=usb TYPE=0/0/0 UDEV_LOG=3 USEC_INITIALIZED=21800816945 UDEV [21800.818645] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3 (usb) ACTION=remove BUSNUM=002 DEVNAME=/dev/bus/usb/002/038 DEVNUM=038 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3 DEVTYPE=usb_device ID_BUS=usb ID_MODEL=USB_Receiver ID_MODEL_ENC=USB\x20Receiver ID_MODEL_ID=c51a ID_REVISION=4100 ID_SERIAL=Logitech_USB_Receiver ID_USB_INTERFACES=:030102:030000: ID_VENDOR=Logitech ID_VENDOR_ENC=Logitech ID_VENDOR_ID=046d MAJOR=189 MINOR=165 PRODUCT=46d/c51a/4100 SEQNUM=3190 SUBSYSTEM=usb TYPE=0/0/0 UDEV_LOG=3 UPOWER_VENDOR=Logitech, Inc. USEC_INITIALIZED=21796488421 и понять что там к чему. Добавить к существующему правилу ACTION=="add" тогда оно будет срабатывать только при подключении устройства. А вот что писать в ACTION=="remove" что бы systemd стопил сервис - я не знаю. Но мне кажется, остановки с помощью BindsTo= вполне достаточно. Ответ на 3) При выполнении /usr/sbin/pppd call modem он разве не завершается? Там другой процесс порождается демоном, но systemd об этом ничего не знает. Если хочется, то можете попробывать заставить systemd мониторить процесс с помощью Type=forking и, желательно, PIDFile=. Как там работает pppd я не в курсе, может поможет GuessMainPID=yes (хотя если PIDFile пуст, то он по умолчанию вкл). По управлению udev: Может быть полезно сгенерировать различные события udev. Например, вы хотите симулировать отключение USB-устройства на удаленной машине. В таких случаях, используйте udevadm trigger: udevadm trigger -v -t subsystems -c remove -s usb -a "idVendor=id_поставщика" У тебя соответственно -s ttyACM. Хотя тут я не уверен, потому что сам плохо знаю этот момент.

четверг, 5 декабря 2019 г.

Закрытый API - доступ открыт

#java #android #модемы


Уже почти целую неделю ищу способы пробиться в com.android.internal.telephony.IccCard
и овладеть методом supplyDepersonalization(). Тем, кто тоже будет копать в эту сторону
- ничего не получится. Даже с помощью рефлексии - это невозможно.
Единственный способ (не знаю, первый ли я):


Найти на устройстве (с правами root) фреймворк модема system/framework/telephony-common.jar
Любым архиватором достать из него скомпилированный classes.dex
"Превратить" его в jar утилитой dex2jar
И добавить полученный архив в вашу среду разработки


Лично у меня AIDE и я просто разархивировал android.jar и добавил в его содержимое
полученный ранее архив.

В итоге

Теперь мы можем написать в секции импортов, например, так

import com.android.internal.telephony.RIL;


И делать все, что хочется. Дело в том, что весь код, связанный с добавленными классами
успешно скомпилируется и будет выполняться. Я это проверил, вызывая методы в разных
классах и получая возвращаемые значения. 

Теперь к делу

Собственно, сам вопрос, я пытаюсь получить интерфейс IccCard и делаю так

PhoneFactory.makeDefaultPhone(this);
Phone p = PhoneFactory.getDefaultPhone();
IccCard i = p.getIccCard();
boolean x = i.getIccLockEnabled();


В итоге приложение зависает (и даже не показывает простую разметку) при выполнении
метода makeDefaultPhone(). Мне стало интересно почему и я полез его искать:

public static void makeDefaultPhone(Context context
    synchronized(Phone.class) {
if (!sMadeDefaults) {
sLooper = Looper.myLooper();
sContext = context;
if (sLooper == null) {
throw new RuntimeException("PhoneFactory.makeDefaultPhone must be called from Looper
thread");
}
int retryCount = 0;
for(;;) {
boolean hasException = false;
retryCount ++;
try {
// use UNIX domain socket to
// prevent subsequent initialization
new LocalServerSocket("com.android.internal.telephony");
} catch (java.io.IOException ex) {
hasException = true;
}
if ( !hasException ) {
break;
} else if (retryCount > SOCKET_OPEN_MAX_RETRY) {
throw new RuntimeException("PhoneFactory probably already running");
} else {
try {
Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
} catch (InterruptedException er) {
}
}
}
sPhoneNotifier = new DefaultPhoneNotifier();
// Get preferred network mode
int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE;
if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
preferredNetworkMode = Phone.NT_MODE_GLOBAL;
}
int networkMode = Settings.Global.getInt(context.getContentResolver(), Settings.Global.PREFERRED_NETWORK_MODE,
preferredNetworkMode);
Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode));
int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);
Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
//reads the system properties and makes commandsinterface
sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
// Instantiate UiccController so that all other classes can just call getInstance()
UiccController.make(context, sCommandsInterface);
int phoneType = TelephonyManager.getPhoneType(networkMode);
if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
Rlog.i(LOG_TAG, "Creating GSMPhone");
sProxyPhone = new PhoneProxy(new GSMPhone(context, sCommandsInterface, sPhoneNotifier));
} else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
switch (TelephonyManager.getLteOnCdmaModeStatic()) {
case PhoneConstants.LTE_ON_CDMA_TRUE:
Rlog.i(LOG_TAG, "Creating CDMALTEPhone");
sProxyPhone = new PhoneProxy(new CDMALTEPhone(context, sCommandsInterface, sPhoneNotifier));
break;
case PhoneConstants.LTE_ON_CDMA_FALSE:
default:
Rlog.i(LOG_TAG, "Creating CDMAPhone");
sProxyPhone = new PhoneProxy(new CDMAPhone(context, sCommandsInterface, sPhoneNotifier));
break;
}
}
// Ensure that we have a default SMS app. Requesting the app with
// updateIfNeeded set to true is enough to configure a default SMS app.
ComponentName componentName = SmsApplication.getDefaultSmsApplication(context, true
/* updateIfNeeded */);
String packageName = "NONE";
if (componentName != null) {
packageName = componentName.getPackageName();
}
Rlog.i(LOG_TAG, "defaultSmsApplication: " + packageName);
// Set up monitor to watch for changes to SMS packages
SmsApplication.initSmsPackageMonitor(context);
sMadeDefaults = true;
}
}
}


Ну, что ж, внимательно почитав код и разобрав каждую строчку, я понял, что мне не
нужно обращаться к PhoneFactory. Достаточно создать Phone самому. Пытаюсь так:

int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(this);
            PhoneNotifier sPhoneNotifier = new DefaultPhoneNotifier();
            RIL sRIL = new RIL(this, 9, cdmaSubscription);
            CommandsInterface sCommandsInterface = sRIL;
            GSMPhone gsmPhone = new GSMPhone(this, sCommandsInterface, sPhoneNotifier);
Phone sProxyPhone = new PhoneProxy(gsmPhone);


DefaultPhoneNotifier имеет конструктор с модификатором доступа protected. Причем,
в официальной документацит его вообще нет (public). Мой фреймворк был модифицирован
производителем. Что можно в таком случае предпринять? Можно ли создать PhoneNotifier
как-нибудь по другому? Как отправлять код разлочки по-другому? 

UPDATE

Фреймворк на тестируемом устройстве вовсе не модифицирован. Заметил, что в разных
версиях андроида где-то protected есть, а где то нет. 
    


Ответы

Ответ 1



жениться бы вам надо, барин... Все что делает supplyDepersonalization() - это шлет модему команду AT+CLCK="PS",0,. Проблема в том, что PS (т.е. SIM Lock) услуга давно не поддерживается производителями модемов (baseband). Попробуйте послать модему команду AT+CLCK=? которая возвращает список поддерживаемых вариантов залочки. И если в нем не будет PS - то никакое извращение на стороне Андроида (application processor) вам не поможет.

вторник, 27 ноября 2018 г.

Раздать интернет

Почему
$ ping ya.ru ping: unknown host ya.ru
Комп1 (принимающий инет)
$ ifconfig wlan0 wlan0 Link encap:Ethernet HWaddr b8:03:05:c9:3e:c5 inet addr:192.168.0.2 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::ba03:5ff:fec9:3ec5/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:33086 errors:0 dropped:0 overruns:0 frame:0 TX packets:62823 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2797459 (2.7 MB) TX bytes:90723494 (90.7 MB)
и так делал
$ ip route default via 192.168.0.2 dev wlan0 scope link metric 100 192.168.0.0/24 dev wlan0 proto kernel scope link src 192.168.0.2 metric 9
и так делал
$ ip route default via 192.168.0.1 dev wlan0 scope link metric 100 192.168.0.0/24 dev wlan0 proto kernel scope link src 192.168.0.2 metric 9
$ sudo iptables-save :пусто

$ nslookup ya.ru ;; connection timed out; no servers could be reached
$ ping 8.8.8.8 connect: Network is unreachable

Комп2 (раздающий 3g)
$ ifconfig -a eth0 Link encap:Ethernet HWaddr b8:88:e3:67:d4:45 UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:5976 errors:0 dropped:0 overruns:0 frame:0 TX packets:5976 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:547759 (547.7 KB) TX bytes:547759 (547.7 KB)
ppp0 Link encap:Point-to-Point Protocol inet addr:10.225.20.196 P-t-P:10.64.64.64 Mask:255.255.255.255 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1 RX packets:14699 errors:0 dropped:0 overruns:0 frame:0 TX packets:13627 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:3 RX bytes:11287729 (11.2 MB) TX bytes:2950024 (2.9 MB)
wlan0 Link encap:Ethernet HWaddr 50:b7:c3:2a:68:31 inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::52b7:c3ff:fe2a:6831/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1000 errors:0 dropped:0 overruns:0 frame:0 TX packets:1021 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:148348 (148.3 KB) TX bytes:108966 (108.9 KB)
wwan0 Link encap:Ethernet HWaddr 58:2c:80:13:92:63 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
$ ip route default via 10.64.64.64 dev ppp0 metric 100 10.64.64.64 dev ppp0 proto kernel scope link src 10.225.20.196 192.168.0.0/24 dev wlan0 proto kernel scope link src 192.168.0.1 metric 9
net.ipv4.ip_forward = 1
Даже после команды :
$ sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -d 10.0.0.0/24 -o ppp0 -j MASQUERADE
в iptables пусто
$ sudo iptables -L -v -n --line Chain INPUT (policy ACCEPT 11498 packets, 8572K bytes) num pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 2 packets, 112 bytes) num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 11183 packets, 2394K bytes) num pkts bytes target prot opt in out source destination
$ sudo iptables-save # Generated by iptables-save v1.4.21 on Fri Aug 12 21:04:53 2016 *nat :PREROUTING ACCEPT [437:43281] :INPUT ACCEPT [389:28232] :OUTPUT ACCEPT [1207:218579] :POSTROUTING ACCEPT [66:9831] -A POSTROUTING -o ppp0 -j MASQUERADE COMMIT # Completed on Fri Aug 12 21:04:53 2016 # Generated by iptables-save v1.4.21 on Fri Aug 12 21:04:53 2016 *filter :INPUT ACCEPT [29340:31886316] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [21601:3071749] -A FORWARD -s 192.168.0.0/24 -i wlan0 -o ppp0 -j ACCEPT -A FORWARD -d 192.168.0.0/24 -i ppp0 -o wlan0 -j ACCEPT COMMIT # Completed on Fri Aug 12 21:04:53 2016
$ nslookup ya.ru Server: 127.0.1.1 Address: 127.0.1.1#53
Non-authoritative answer: Name: ya.ru Address: 93.158.134.3 Name: ya.ru Address: 213.180.193.3 Name: ya.ru Address: 213.180.204.3
Сделал :
iptables -F iptables -X iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE iptables -A FORWARD -i wlan0 -o ppp0 -s 192.168.0.0/24 -j ACCEPT iptables -A FORWARD -i ppp0 -o wlan0 -d 192.168.0.0/24 -j ACCEPT
Получил
$ sudo iptables -t nat -nvL Chain PREROUTING (policy ACCEPT 72 packets, 4357 bytes) pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 65 packets, 3965 bytes) pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 88 packets, 13008 bytes) pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 5 packets, 890 bytes) pkts bytes target prot opt in out source destination 90 12510 MASQUERADE all -- * ppp0 0.0.0.0/0 0.0.0.0/0
Но маскарад так и не работает.

В итоге на комп2 есть инет и пингуется комп1. А на комп1 нет инета,хотя и пингуется комп2. Почему нет интернета ?(


Ответ

На обоих компах прописал в файл /etc/resolv.conf
nameserver 8.8.8.8
Спасибо @alexander-barakin
Сделал на компе2(с 3g инетом):
iptables -F iptables -X iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE iptables -A FORWARD -i wlan0 -o ppp0 -s 192.168.0.0/24 -j ACCEPT iptables -A FORWARD -i ppp0 -o wlan0 -d 192.168.0.0/24 -j ACCEPT
Спасибо @nobody
И заработало. Всем спасибо!)

четверг, 11 октября 2018 г.

systemd/udev: запуск демона при подключении модема и остановка демона при отсоединении модема

Возможно ли в systemd/udev реализовать так, чтобы при появлении в системе модема (/dev/ttyACM%i) запускался демон modem@%i.service, и чтобы при отключении модема демон останавливался?
Готовый полный универсальный рабочий рецепт.
/etc/ppp/peers/modem
460800 defaultroute usepeerdns crtscts lock noauth local persist modem nopcomp novjccomp nobsdcomp nodeflate noaccomp ipcp-accept-local ipcp-accept-remote noipdefault connect "/usr/sbin/chat -t10 -f /etc/ppp/chatscripts/modem.chat"
/etc/ppp/chatscripts/modem.chat
В поле точки доступа "internet.mts.ru" или подставьте точку доступа своего провайдера или оставьте такой, если у вас российский МТС. Большинство провайдеров игнорируют это поле, и его вообще можно не указывать, но МТС её требует и без неё не соединяет.
ABORT 'BUSY' ABORT 'NO CARRIER' ABORT 'VOICE' ABORT 'NO DIALTONE' ABORT 'NO DIAL TONE' ABORT 'NO ANSWER' ABORT 'DELAYED' REPORT CONNECT TIMEOUT 5 '' 'ATQ0' 'OK-AT-OK' 'ATZ' TIMEOUT 3 'OK-AT-OK' 'ATI' 'OK' 'ATZ' 'OK' 'ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0' 'OK' 'AT\^SYSCFG=2,2,3fffffff,0,1' 'OK-AT-OK' 'AT+CGDCONT=1,"IP","internet.mts.ru"' 'OK' 'ATDT*99#' CONNECT
/usr/lib/systemd/system/modem@.service
[Unit] Description=Modem /dev/ttyACM%i BindsTo=dev-ttyACM%i.device After=dev-ttyACM%i.device Before=network.target Wants=network.target
[Service] ExecStart=/usr/sbin/pppd call modem /dev/ttyACM%i
[Install] WantedBy=multi-user.target
/etc/udev/rules.d/90-modem.rules
KERNEL=="ttyACM[0-9]*", TAG+="systemd", ENV{SYSTEMD_WANTS}="modem@%n.service"
Затем перезагрузить конфигурацию systemd.
sudo systemctl daemon-reload
И теперь достаточно просто подключить любой телефон, кроме огрызка, с любым оператором в режим не накопителя. (Nokia suite, Телефон, Модем, Синхронизация и т.д.)
Ну, конечно же, желательно убедиться, что у вас определяется модем и его файл устройства, как у меня, /dev/ttyACM0 и udev на него ссылается как dev-ttyACM0.device, а не /dev/ttyUSB0 и dev-ttyUSB0.device или как-то иначе. Цифру, обозначающую порядковый номер устройства (0) в демоне systemd заменяем на %i, а в правилах udev на %n. Это даёт возможность не привязывать демон и правила только к одному модему, а работать с неограниченным количеством модемов и корректно управлять каждым модемом отдельно друг от друга.
systemctl list-units -tdevice -a | grep dev-tty
Телефон теперь всегда подключается к интернету при подключении к компьютеру, даже если компьютер успешно подключён через ethernet или Wi-Fi к интернету. Правда, в этом случае, когда в системе поднят (ifup) хоть 1 интерфейс, трафик идёт через него, а с модемом лишь устанавливает соединение, но передачи данных не происходит.
Чтобы отключить автодозвон при подключении модема нужно просто замаскировать демон sudo systemctl mask modem@0.service, а потом, когда понадобится модем размаскировать sudo systemctl unmask modem@0.service 0 - это порядковый номер модема, если у вас их несколько, то можно отключить ненужные или отключить все.
И самое не приятное, если ethernet и/или Wi-Fi подняты (ifup), то трафик не будет идти через модем, пока все интерфейсы не будут опущены (ifdown) даже если к ним не подключен кабель или нет выхода в интернет. Но это уже особенность модемной маршрутизации.


Ответ

Правильнее будет, чтобы udev запускал/останавливал systemd.service — это его работа.
my.service
[Unit] Description=Modem ppp0 <--> /dev/ttyACM0 BindsTo=dev-ttyACM0.device After=dev-ttyACM0.device Before=network.target Wants=network.target
[Service] ExecStart=/usr/sbin/pppd call modem ExecStop=комманда на стоп KillMode=none Type=oneshot RemainAfterExit=yes
[Install] WantedBy=multi-user.target
Список всех устройств, но со своим ты уже разобрался: systemctl list-units --all --full | grep ".device"
90-my.rules в папку /etc/udev/rules.d/
KERNEL=="ttyACM*", ATTRS{serial}=="<СЕРИЙНИК>", TAG+="systemd", ENV{SYSTEMD_WANTS}="my.service"
Можно добавить SYMLINK=="gsmmodem", тогда появится симлинк /dev/gsmmodem.
А ATTR{serial} или подобные нужны, чтобы не спутать разные устройства.
Получить серийник и прочие аттрибуты: udevadm info -a -n /dev/ttyACM*
UPD
Можно сделать так, чтобы из KERNEL=="ttyACM*" передавался номер устройства (цифра под звёздочкой) в сервис, которая бы потом дополняла бы строку запуска? 2.a Или будет всё же проще и лучше написать 2 демона (modem0.service и modem1.service) для ACM0 и ACM1?
Для этого тебе нужен не просто сервис, а шаблонный сервис. Для этого переименуй my.service в my@.service и запускать их мы будем как my@ttyACM0.service и my@ttyACM1.service, тогда внутри файла тебе будут доступны такие переменные как %i %I (которые и будут именем сервиса, тот что после @). Меняешь все упоминания ttyACMX на %I и наслаждаешься =)
Внутри udev доступны операторы %k and %n, это имя и номер соответственно (ты просил именно %k). Соответственно, исправляешь ENV{SYSTEMD_WANTS}="my@%k.service" и будет стартовать сервис my@ttyACM0.service
По поводу отключения. Тут сложнее, потому что когда устройство отключается, то его параметры становятся недоступны и уже сложно понять что же было отключено, можешь запустить udevadm monitor --environment --udev и выдернуть устройство, должен увидеть что-то типа
#######REMOVE#######
monitor will print the received events for: UDEV - the event which udev sends out after rule processing
UDEV [21800.789239] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input75/mouse1 (input) ACTION=remove DEVLINKS=/dev/input/by-id/usb-Logitech_USB_Receiver-mouse /dev/input/by-path/pci-0000:00:1d.0-usb-0:1.3:1.0-mouse DEVNAME=/dev/input/mouse1 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input75/mouse1 ID_BUS=usb ID_INPUT=1 ID_INPUT_MOUSE=1 ID_MODEL=USB_Receiver ID_MODEL_ENC=USB\x20Receiver ID_MODEL_ID=c51a ID_PATH=pci-0000:00:1d.0-usb-0:1.3:1.0 ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_3_1_0 ID_REVISION=4100 ID_SERIAL=Logitech_USB_Receiver ID_TYPE=hid ID_USB_DRIVER=usbhid ID_USB_INTERFACES=:030102:030000: ID_USB_INTERFACE_NUM=00 ID_VENDOR=Logitech ID_VENDOR_ENC=Logitech ID_VENDOR_ID=046d MAJOR=13 MINOR=33 SEQNUM=3178 SUBSYSTEM=input UDEV_LOG=3 USEC_INITIALIZED=21797014959
UDEV [21800.792866] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input75/event6 (input) ACTION=remove DEVLINKS=/dev/input/by-id/usb-Logitech_USB_Receiver-event-mouse /dev/input/by-path/pci-0000:00:1d.0-usb-0:1.3:1.0-event-mouse DEVNAME=/dev/input/event6 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input75/event6 ID_BUS=usb ID_INPUT=1 ID_INPUT_MOUSE=1 ID_MODEL=USB_Receiver ID_MODEL_ENC=USB\x20Receiver ID_MODEL_ID=c51a ID_PATH=pci-0000:00:1d.0-usb-0:1.3:1.0 ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_3_1_0 ID_REVISION=4100 ID_SERIAL=Logitech_USB_Receiver ID_TYPE=hid ID_USB_DRIVER=usbhid ID_USB_INTERFACES=:030102:030000: ID_USB_INTERFACE_NUM=00 ID_VENDOR=Logitech ID_VENDOR_ENC=Logitech ID_VENDOR_ID=046d MAJOR=13 MINOR=70 SEQNUM=3179 SUBSYSTEM=input UDEV_LOG=3 USEC_INITIALIZED=21797013896
UDEV [21800.797061] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input75 (input) ACTION=remove DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input75 EV=17 ID_BUS=usb ID_INPUT=1 ID_INPUT_MOUSE=1 ID_MODEL=USB_Receiver ID_MODEL_ENC=USB\x20Receiver ID_MODEL_ID=c51a ID_PATH=pci-0000:00:1d.0-usb-0:1.3:1.0 ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_3_1_0 ID_REVISION=4100 ID_SERIAL=Logitech_USB_Receiver ID_TYPE=hid ID_USB_DRIVER=usbhid ID_USB_INTERFACES=:030102:030000: ID_USB_INTERFACE_NUM=00 ID_VENDOR=Logitech ID_VENDOR_ENC=Logitech ID_VENDOR_ID=046d KEY=ffff0000 0 0 0 0 0 0 0 0 MODALIAS=input:b0003v046DpC51Ae0111-e0,1,2,4,k110,111,112,113,114,115,116,117,118,119,11A,11B,11C,11D,11E,11F,r0,1,6,8,am4,lsfw MSC=10 NAME="Logitech USB Receiver" PHYS="usb-0000:00:1d.0-1.3/input0" PRODUCT=3/46d/c51a/111 PROP=0 REL=143 SEQNUM=3180 SUBSYSTEM=input UDEV_LOG=3 UNIQ="" USEC_INITIALIZED=21796479085
UDEV [21800.797132] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/0003:046D:C51A.004D/hidraw/hidraw2 (hidraw) ACTION=remove DEVNAME=/dev/hidraw2 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/0003:046D:C51A.004D/hidraw/hidraw2 MAJOR=251 MINOR=2 SEQNUM=3181 SUBSYSTEM=hidraw UDEV_LOG=3 USEC_INITIALIZED=21800796369
UDEV [21800.797172] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/0003:046D:C51A.004D (hid) ACTION=remove DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/0003:046D:C51A.004D HID_ID=0003:0000046D:0000C51A HID_NAME=Logitech USB Receiver HID_PHYS=usb-0000:00:1d.0-1.3/input0 MODALIAS=hid:b0003g0001v0000046Dp0000C51A SEQNUM=3182 SUBSYSTEM=hid UDEV_LOG=3 USEC_INITIALIZED=21800796501
UDEV [21800.798537] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0 (usb) ACTION=remove DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0 DEVTYPE=usb_interface INTERFACE=3/1/2 MODALIAS=usb:v046DpC51Ad4100dc00dsc00dp00ic03isc01ip02in00 PRODUCT=46d/c51a/4100 SEQNUM=3183 SUBSYSTEM=usb TYPE=0/0/0 UDEV_LOG=3 USEC_INITIALIZED=21800796538
UDEV [21800.814181] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/input/input76/event7 (input) ACTION=remove DEVLINKS=/dev/input/by-id/usb-Logitech_USB_Receiver-event-if01 /dev/input/by-path/pci-0000:00:1d.0-usb-0:1.3:1.1-event DEVNAME=/dev/input/event7 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/input/input76/event7 ID_BUS=usb ID_INPUT=1 ID_INPUT_KEY=1 ID_MODEL=USB_Receiver ID_MODEL_ENC=USB\x20Receiver ID_MODEL_ID=c51a ID_PATH=pci-0000:00:1d.0-usb-0:1.3:1.1 ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_3_1_1 ID_REVISION=4100 ID_SERIAL=Logitech_USB_Receiver ID_TYPE=hid ID_USB_DRIVER=usbhid ID_USB_INTERFACES=:030102:030000: ID_USB_INTERFACE_NUM=01 ID_VENDOR=Logitech ID_VENDOR_ENC=Logitech ID_VENDOR_ID=046d MAJOR=13 MINOR=71 SEQNUM=3184 SUBSYSTEM=input UDEV_LOG=3 USEC_INITIALIZED=21797013933 XKBLAYOUT=de XKBMODEL=pc105
UDEV [21800.816765] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/input/input76 (input) ABS=1 0 ACTION=remove DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/input/input76 EV=1f ID_BUS=usb ID_INPUT=1 ID_INPUT_KEY=1 ID_MODEL=USB_Receiver ID_MODEL_ENC=USB\x20Receiver ID_MODEL_ID=c51a ID_PATH=pci-0000:00:1d.0-usb-0:1.3:1.1 ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_3_1_1 ID_REVISION=4100 ID_SERIAL=Logitech_USB_Receiver ID_TYPE=hid ID_USB_DRIVER=usbhid ID_USB_INTERFACES=:030102:030000: ID_USB_INTERFACE_NUM=01 ID_VENDOR=Logitech ID_VENDOR_ENC=Logitech ID_VENDOR_ID=046d KEY=4837fff 72ff32d bf544446 0 0 1 20f90 8b17c000 677bfa d9415fed 9ed680 4400 0 10000002 MODALIAS=input:b0003v046DpC51Ae0111-e0,1,2,3,4,k71,72,73,74,77,80,82,83,85,86,87,88,89,8A,8B,8C,8E,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7,A8,A9,AB,AC,AD,AE,B0,B1,B2,B5,B6,CE,CF,D0,D1,D2,D4,D8,D9,DB,DF,E4,E7,E8,E9,EA,EB,F1,100,161,162,166,16A,16E,172,174,176,178,179,17A,17B,17C,17D,17F,180,182,183,185,188,189,18C,18D,18E,18F,190,191,192,193,195,198,199,19A,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA,1AB,1AC,1AD,1AE,1B0,1B1,1B7,1BA,r6,a20,m4,lsfw MSC=10 NAME="Logitech USB Receiver" PHYS="usb-0000:00:1d.0-1.3/input1" PRODUCT=3/46d/c51a/111 PROP=0 REL=40 SEQNUM=3185 SUBSYSTEM=input UDEV_LOG=3 UNIQ="" USEC_INITIALIZED=21796482192
UDEV [21800.817249] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/usbmisc/hiddev1 (usbmisc) ACTION=remove DEVNAME=/dev/usb/hiddev1 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/usbmisc/hiddev1 MAJOR=180 MINOR=1 SEQNUM=3186 SUBSYSTEM=usbmisc UDEV_LOG=3 USEC_INITIALIZED=21800816392
UDEV [21800.818490] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/0003:046D:C51A.004E/hidraw/hidraw3 (hidraw) ACTION=remove DEVNAME=/dev/hidraw3 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/0003:046D:C51A.004E/hidraw/hidraw3 MAJOR=251 MINOR=3 SEQNUM=3187 SUBSYSTEM=hidraw UDEV_LOG=3 USEC_INITIALIZED=21800816472
UDEV [21800.818536] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/0003:046D:C51A.004E (hid) ACTION=remove DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/0003:046D:C51A.004E HID_ID=0003:0000046D:0000C51A HID_NAME=Logitech USB Receiver HID_PHYS=usb-0000:00:1d.0-1.3/input1 MODALIAS=hid:b0003g0001v0000046Dp0000C51A SEQNUM=3188 SUBSYSTEM=hid UDEV_LOG=3 USEC_INITIALIZED=21800816908
UDEV [21800.818580] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1 (usb) ACTION=remove DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1 DEVTYPE=usb_interface INTERFACE=3/0/0 MODALIAS=usb:v046DpC51Ad4100dc00dsc00dp00ic03isc00ip00in01 PRODUCT=46d/c51a/4100 SEQNUM=3189 SUBSYSTEM=usb TYPE=0/0/0 UDEV_LOG=3 USEC_INITIALIZED=21800816945
UDEV [21800.818645] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3 (usb) ACTION=remove BUSNUM=002 DEVNAME=/dev/bus/usb/002/038 DEVNUM=038 DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3 DEVTYPE=usb_device ID_BUS=usb ID_MODEL=USB_Receiver ID_MODEL_ENC=USB\x20Receiver ID_MODEL_ID=c51a ID_REVISION=4100 ID_SERIAL=Logitech_USB_Receiver ID_USB_INTERFACES=:030102:030000: ID_VENDOR=Logitech ID_VENDOR_ENC=Logitech ID_VENDOR_ID=046d MAJOR=189 MINOR=165 PRODUCT=46d/c51a/4100 SEQNUM=3190 SUBSYSTEM=usb TYPE=0/0/0 UDEV_LOG=3 UPOWER_VENDOR=Logitech, Inc. USEC_INITIALIZED=21796488421
и понять что там к чему. Добавить к существующему правилу ACTION=="add" тогда оно будет срабатывать только при подключении устройства. А вот что писать в ACTION=="remove" что бы systemd стопил сервис - я не знаю. Но мне кажется, остановки с помощью BindsTo= вполне достаточно.
Ответ на 3) При выполнении /usr/sbin/pppd call modem он разве не завершается? Там другой процесс порождается демоном, но systemd об этом ничего не знает. Если хочется, то можете попробывать заставить systemd мониторить процесс с помощью Type=forking и, желательно, PIDFile=. Как там работает pppd я не в курсе, может поможет GuessMainPID=yes (хотя если PIDFile пуст, то он по умолчанию вкл).
По управлению udev:
Может быть полезно сгенерировать различные события udev. Например, вы хотите симулировать отключение USB-устройства на удаленной машине. В таких случаях, используйте udevadm trigger: udevadm trigger -v -t subsystems -c remove -s usb -a "idVendor=id_поставщика"
У тебя соответственно -s ttyACM. Хотя тут я не уверен, потому что сам плохо знаю этот момент.

вторник, 9 октября 2018 г.

Закрытый API - доступ открыт

Уже почти целую неделю ищу способы пробиться в com.android.internal.telephony.IccCard и овладеть методом supplyDepersonalization(). Тем, кто тоже будет копать в эту сторону - ничего не получится. Даже с помощью рефлексии - это невозможно. Единственный способ (не знаю, первый ли я):
Найти на устройстве (с правами root) фреймворк модема system/framework/telephony-common.jar Любым архиватором достать из него скомпилированный classes.dex "Превратить" его в jar утилитой dex2jar И добавить полученный архив в вашу среду разработки
Лично у меня AIDE и я просто разархивировал android.jar и добавил в его содержимое полученный ранее архив.
В итоге
Теперь мы можем написать в секции импортов, например, так
import com.android.internal.telephony.RIL;
И делать все, что хочется. Дело в том, что весь код, связанный с добавленными классами успешно скомпилируется и будет выполняться. Я это проверил, вызывая методы в разных классах и получая возвращаемые значения.
Теперь к делу
Собственно, сам вопрос, я пытаюсь получить интерфейс IccCard и делаю так
PhoneFactory.makeDefaultPhone(this); Phone p = PhoneFactory.getDefaultPhone(); IccCard i = p.getIccCard(); boolean x = i.getIccLockEnabled();
В итоге приложение зависает (и даже не показывает простую разметку) при выполнении метода makeDefaultPhone(). Мне стало интересно почему и я полез его искать:
public static void makeDefaultPhone(Context context synchronized(Phone.class) { if (!sMadeDefaults) { sLooper = Looper.myLooper(); sContext = context; if (sLooper == null) { throw new RuntimeException("PhoneFactory.makeDefaultPhone must be called from Looper thread"); } int retryCount = 0; for(;;) { boolean hasException = false; retryCount ++; try { // use UNIX domain socket to // prevent subsequent initialization new LocalServerSocket("com.android.internal.telephony"); } catch (java.io.IOException ex) { hasException = true; } if ( !hasException ) { break; } else if (retryCount > SOCKET_OPEN_MAX_RETRY) { throw new RuntimeException("PhoneFactory probably already running"); } else { try { Thread.sleep(SOCKET_OPEN_RETRY_MILLIS); } catch (InterruptedException er) { } } } sPhoneNotifier = new DefaultPhoneNotifier(); // Get preferred network mode int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE; if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) { preferredNetworkMode = Phone.NT_MODE_GLOBAL; } int networkMode = Settings.Global.getInt(context.getContentResolver(), Settings.Global.PREFERRED_NETWORK_MODE, preferredNetworkMode); Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode)); int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context); Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription); //reads the system properties and makes commandsinterface sCommandsInterface = new RIL(context, networkMode, cdmaSubscription); // Instantiate UiccController so that all other classes can just call getInstance() UiccController.make(context, sCommandsInterface); int phoneType = TelephonyManager.getPhoneType(networkMode); if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { Rlog.i(LOG_TAG, "Creating GSMPhone"); sProxyPhone = new PhoneProxy(new GSMPhone(context, sCommandsInterface, sPhoneNotifier)); } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { switch (TelephonyManager.getLteOnCdmaModeStatic()) { case PhoneConstants.LTE_ON_CDMA_TRUE: Rlog.i(LOG_TAG, "Creating CDMALTEPhone"); sProxyPhone = new PhoneProxy(new CDMALTEPhone(context, sCommandsInterface, sPhoneNotifier)); break; case PhoneConstants.LTE_ON_CDMA_FALSE: default: Rlog.i(LOG_TAG, "Creating CDMAPhone"); sProxyPhone = new PhoneProxy(new CDMAPhone(context, sCommandsInterface, sPhoneNotifier)); break; } } // Ensure that we have a default SMS app. Requesting the app with // updateIfNeeded set to true is enough to configure a default SMS app. ComponentName componentName = SmsApplication.getDefaultSmsApplication(context, true /* updateIfNeeded */); String packageName = "NONE"; if (componentName != null) { packageName = componentName.getPackageName(); } Rlog.i(LOG_TAG, "defaultSmsApplication: " + packageName); // Set up monitor to watch for changes to SMS packages SmsApplication.initSmsPackageMonitor(context); sMadeDefaults = true; } } }
Ну, что ж, внимательно почитав код и разобрав каждую строчку, я понял, что мне не нужно обращаться к PhoneFactory. Достаточно создать Phone самому. Пытаюсь так:
int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(this); PhoneNotifier sPhoneNotifier = new DefaultPhoneNotifier(); RIL sRIL = new RIL(this, 9, cdmaSubscription); CommandsInterface sCommandsInterface = sRIL; GSMPhone gsmPhone = new GSMPhone(this, sCommandsInterface, sPhoneNotifier); Phone sProxyPhone = new PhoneProxy(gsmPhone);
DefaultPhoneNotifier имеет конструктор с модификатором доступа protected. Причем, в официальной документацит его вообще нет (public). Мой фреймворк был модифицирован производителем. Что можно в таком случае предпринять? Можно ли создать PhoneNotifier как-нибудь по другому? Как отправлять код разлочки по-другому?
UPDATE
Фреймворк на тестируемом устройстве вовсе не модифицирован. Заметил, что в разных версиях андроида где-то protected есть, а где то нет.


Ответ

жениться бы вам надо, барин...
Все что делает supplyDepersonalization() - это шлет модему команду AT+CLCK="PS",0,. Проблема в том, что PS (т.е. SIM Lock) услуга давно не поддерживается производителями модемов (baseband).
Попробуйте послать модему команду AT+CLCK=? которая возвращает список поддерживаемых вариантов залочки. И если в нем не будет PS - то никакое извращение на стороне Андроида (application processor) вам не поможет.