aboutsummaryrefslogtreecommitdiff
path: root/plugins/simtech
AgeCommit message (Collapse)Author
2023-01-03build: move plugins directory to src/pluginsAleksander Morgado
We are going to allow including the plugin sources built within the ModemManager daemon binary; moving the sources within the daemon sources directory makes it easier.
2022-09-05core: port GRegex/GMatchInfo to use autoptr()Aleksander Morgado
The behavior of GRegex changed in 2.73.2 once it was ported from pcre1 to pcre2. In some cases it was made more strict, which is fine, in other cases it exposed some change in how it behaves on certain matches that is not extremely clear whether it's ok or not. See https://gitlab.gnome.org/GNOME/glib/-/issues/2729 See https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/601 See https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/621 Either way, one thing that was assumed was that initializing all GRegex/GMatchInfo variables to NULL and making sure they're NULL before they're initialized by glib (especially the GMatchInfo) was a good and safer approach. So, whenever possible, g_autoptr() is used to cleanup the allocated GMatchInfo/GRegex variables, and otherwise, g_clear_pointer() is used to ensure that no free/unref is attempted unless the given variable is not NULL, and also so that the variable is reseted to NULL after being disposed.
2022-05-24base-modem: add subsystem vendor ID propertyDaniele Palmas
Subsystem vendor ID can be used for identifying PCI modems, so expose the property.
2022-05-20iface-modem: remove MM_IFACE_MODEM_SIM_HOT_SWAP_CONFIGURED propertyAleksander Morgado
This property is used in the MMIfaceModem to flag whether the SIM hot swap setup has been performed or not. The flag is now moved to the iface-specific private context. The property was also used in AT-based modems, so that implementations supporting the SIM hot swap via AT URCs could flag the upper layers whether the enabling of the feature was done correctly or not, and if so, create and keep the AT ports context open. But this feature only made sense in AT-based modems, i.e. an MBIM modem that detects SIM hot swaps via MBIM indications exclusively should not require the AT ports context open for anything. The check in the MMBroadbandModem object has therefore been removed, and the logic will be updated so that it only applies to AT-based modems.
2021-07-14simtech: disable CPOL? checks in SIM7070Aleksander Morgado
The whole device breaks when the CPOL? query is sent; happening consistently all the time: <debug> [1626211395.825257] [modem4/ttyUSB3/at] --> 'AT+CPOL=,2<CR>' <debug> [1626211395.842156] [modem4/ttyUSB3/at] <-- '<CR><LF>OK<CR><LF>' <debug> [1626211395.843227] [modem4/sim4] loading preferred networks... <debug> [1626211395.845289] [modem4/ttyUSB3/at] --> 'AT+CPOL?<CR>' <debug> [1626211401.110974] [modem4/ttyUSB3/at] unexpected port hangup! <debug> [1626211401.111586] [modem4/ttyUSB3/at] forced to close port <debug> [1626211401.112331] [modem4/ttyUSB3/at] closing serial port... <debug> [1626211401.112771] [modem4/ttyUSB3/at] serial port closed Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/401
2021-07-13plugins: AT/QCDM/GPS port type hints only applicable to TTY portsAleksander Morgado
There are modems out there, that reuse the same vid:pid for multiple USB layouts, so there may be port type hints that are not really applicable in all layouts. E.g. the EM7565 in MBIM layout uses interface #0 for the MBIM port, while in QMI layout it uses interface #0 for the QCDM port (which is what the port type hint included in MM states). With these rules, if we don't bind the port type hint to TTY ports only, we would be wrongly flagging the MBIM port as possible QCDM port: <debug> [plugin/sierra] probes required for port cdc-wdm0: 'mbim' <debug> [cdc-wdm0/probe] no AT/QMI/MBIM probing in possible QCDM port <debug> [cdc-wdm0/probe] port is not AT-capable <debug> [cdc-wdm0/probe] port is not QMI-capable <debug> [cdc-wdm0/probe] port is not MBIM-capable <debug> [cdc-wdm0/probe] port probing finished: no more probings needed Avoid this, by making sure all port type hints are added exclusively to TTY ports. It's not a perfect solution, but it's enough for the known cases.
2021-05-26broadband-modem-qmi: assume all QMI based modems support SIM hot swapAleksander Morgado
As we have a generic SIM hot swap implementation in the QMI broadband modem object.
2021-03-04base-modem: explicitly say if NET or TTY data ports are supportedAleksander Morgado
A modem that creates exclusively bearer objects that work with NET ports (e.g. all QMI or MBIM modems) must not add any TTY port in the list of data ports. A modem that creates exclusively bearer objects that work with TTY ports (e.g. the generic modem) must not add any NET port in the list of data ports. A modem that may use both TTY and NET ports should add all in the list of data ports. Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/324 Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/329
2021-01-18simtech: fix updating bitmask during gps disablingLukas Senger
During disabling of gps sources the bitmask that keeps track of them is updated incorrectly. Instead of removing the current source, all other sources are removed from the mask. One problem that arises from this is, that when you enable GPS after it has been disabled completely (e.g. by disabling all GPS sources), the code will not send a "+CGPS=1,1" command because it incorrectly assumes that GPS is still enabled on the device.
2020-11-13core: stop monitoring the 'usb' subsystemAleksander Morgado
Back in Linux < 3.6 days, the cdc-wdm ports exposed by the QMI driver were flagged as owned by the 'usb' subsystem. That changed in 3.6 when the subsystem was renamed to 'usbmisc': https://mail.gnome.org/archives/networkmanager-list/2012-June/msg00125.html This patch removes all monitoring of the 'usb' subsystem completely, which is anyway a valid subsystem but for which we shouldn't need any special handling. Right now, with newer kernels, we were using that monitoring exclusively to get notified of full USB device remove events, which is really not required as we already process the port removals one by one. We simplify the logic everywhere that attempted to match either the 'usb' or 'usbmisc' subsystems, and we no longer require the explicit checks for the port name being named 'cdc-wdm[0-9]*' in the code, as that is already taken care of by the ID_MM_CANDIDATE udev tag rule.
2020-10-14simtech: fix missing GError initializationAleksander Morgado
2020-08-29simtech: add SIM7070/SIM7080/SIM7090 port type hintsAleksander Morgado
These modules have 2 different USB layouts: The default layout with PID 0x9205 (AT+CUSBSELNV=1) exposes 4 TTYs and an ECM interface: T: Bus=02 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 6 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=1e0e ProdID=9205 Rev=00.00 S: Manufacturer=SimTech, Incorporated S: Product=SimTech SIM7080 S: SerialNumber=1234567890ABCDEF C: #Ifs= 6 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#=0x0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option I: If#=0x1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option I: If#=0x2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option I: If#=0x3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option I: If#=0x4 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether I: If#=0x5 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether The purpose of each TTY is as follows: * ttyUSB0: DIAG/QCDM port. * ttyUSB1: GNSS data. * ttyUSB2: AT-capable port (control). * ttyUSB3: AT-capable port (data). In the secondary layout with PID=0x9206 (AT+CUSBSELNV=86) the module exposes 6 TTY ports: T: Bus=02 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=02(commc) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1e0e ProdID=9206 Rev=00.00 S: Manufacturer=SimTech, Incorporated S: Product=SimTech SIM7080 S: SerialNumber=1234567890ABCDEF C: #Ifs= 6 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#=0x0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option I: If#=0x1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option I: If#=0x2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option I: If#=0x3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option I: If#=0x4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option I: If#=0x5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option The purpose of each TTY is as follows: * ttyUSB0: DIAG/QCDM port. * ttyUSB1: GNSS data. * ttyUSB2: AT-capable port (control). * ttyUSB3: QFLOG interface. * ttyUSB4: DAM interface. * ttyUSB5: AT-capable port (data).
2020-04-08plugins: use logging module name as plugin nameAleksander Morgado
2020-04-08log: common logging method definition for all testers and helpersAleksander Morgado
2020-04-08simtech: port to use object loggingAleksander Morgado
2020-04-08modem-helpers: port clcc list parser to use object loggingAleksander Morgado
2020-04-08modem-helpers: port supported modes filtering to use object loggingAleksander Morgado
2020-04-08log: new object logging supportAleksander Morgado
So that we can provide the specific object id in every log associated to a given object.
2020-02-07iface-modem-location: common helper code to test raw gpsAleksander Morgado
2020-01-31simtech: fix warnings with -Wimplicit-fallthroughAleksander Morgado
simtech/mm-broadband-modem-simtech.c: In function ‘enable_unsolicited_events_context_step’: simtech/mm-broadband-modem-simtech.c:442:18: error: this statement may fall through [-Werror=implicit-fallthrough=] 442 | ctx->step++; | ~~~~~~~~~^~ simtech/mm-broadband-modem-simtech.c:444:5: note: here 444 | case ENABLE_UNSOLICITED_EVENTS_STEP_LAST: | ^~~~
2020-01-31simtech: fix warnings with -Wswitch-defaultAleksander Morgado
simtech/mm-broadband-modem-simtech.c: In function ‘enable_unsolicited_events_context_step’: simtech/mm-broadband-modem-simtech.c:378:5: error: switch missing default case [-Werror=switch-default] 378 | switch (ctx->step) { | ^~~~~~ simtech/mm-broadband-modem-simtech.c: In function ‘disable_unsolicited_events_context_step’: simtech/mm-broadband-modem-simtech.c:563:5: error: switch missing default case [-Werror=switch-default] 563 | switch (ctx->step) { | ^~~~~~
2020-01-31simtech: fix warnings with -Wsign-compareAleksander Morgado
simtech/mm-broadband-modem-simtech.c: In function ‘simtech_act_to_mm_act’: simtech/mm-broadband-modem-simtech.c:89:19: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Werror=sign-compare] 89 | return (nsmod < G_N_ELEMENTS (simtech_act_to_mm_act_map) ? simtech_act_to_mm_act_map[nsmod] : MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN); | ^
2020-01-31helpers: new macro to CLAMP high threshold onlyAleksander Morgado
Useful when clamping a unsigned integer with low threshold set to 0, which would give us compiler warnings with -Wtype-limits when using CLAMP(), e.g.: via/mm-broadband-modem-via.c: In function ‘handle_evdo_quality_change’: /usr/include/glib-2.0/glib/gmacros.h:811:63: error: comparison of unsigned expression < 0 is always false [-Werror=type-limits] 811 | #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) | ^ via/mm-broadband-modem-via.c:284:19: note: in expansion of macro ‘CLAMP’ 284 | quality = CLAMP (quality, 0, 100); | ^~~~~
2020-01-31simtech,helpers: fix warnings with -Wdiscarded-qualifiersAleksander Morgado
simtech/tests/test-modem-helpers-simtech.c: In function ‘test_clcc_urc_single’: simtech/tests/test-modem-helpers-simtech.c:98:64: error: initialization discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers] 98 | { 1, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_ACTIVE, "123456789" } | ^~~~~~~~~~~ simtech/tests/test-modem-helpers-simtech.c: In function ‘test_clcc_urc_multiple’: simtech/tests/test-modem-helpers-simtech.c:113:65: error: initialization discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers] 113 | { 2, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_ACTIVE, "123456789" }, | ^~~~~~~~~~~ simtech/tests/test-modem-helpers-simtech.c:114:65: error: initialization discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers] 114 | { 3, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_ACTIVE, "987654321" }, | ^~~~~~~~~~~ simtech/tests/test-modem-helpers-simtech.c: In function ‘test_clcc_urc_complex’: simtech/tests/test-modem-helpers-simtech.c:130:65: error: initialization discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers] 130 | { 1, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_ACTIVE, "123456789" }, | ^~~~~~~~~~~ simtech/tests/test-modem-helpers-simtech.c:131:65: error: initialization discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers] 131 | { 2, MM_CALL_DIRECTION_INCOMING, MM_CALL_STATE_WAITING, "987654321" }, | ^~~~~~~~~~~
2019-10-16simtech: handle 'MISSED_CALL' URCsAleksander Morgado
https://source.puri.sm/Librem5/ModemManager/issues/6
2019-10-16simtech: setup USB audio channel when in-callAleksander Morgado
We'll use +CPCMREG=1/0 to start/stop USB audio function, and we will also report the specific ttyUSB port to be used for audio in the Call interface.
2019-10-15simtech: handle '+RXDTMF' URCs reporting DTMF tonesAleksander Morgado
2019-10-15simtech: handle non-standard '+CRING' URCsAleksander Morgado
The SIM7600E ends up emitting these URCs with too many <CR>s, and the generic +CRING handler doesn't catch them, interfering with other actions, e.g.: $ sudo mmcli --call 1 --accept error: couldn't accept the call: 'GDBus.Error:org.freedesktop.ModemManager1.Error.Core.Failed: Couldn't accept the call: Unhandled response '+CRING: VOICE +CRING: VOICE''
2019-10-15simtech: handle 'VOICE CALL' URCsAleksander Morgado
Just processing and parsing them for now, so that they don't interfere with other commands: $ sudo mmcli --call 1 --accept error: couldn't accept the call: 'GDBus.Error:org.freedesktop.ModemManager1.Error.Core.Failed: Couldn't accept the call: Unhandled response ' VOICE CALL: BEGIN''
2019-10-14simtech: implement +CLCC URC based call list managementAleksander Morgado
2019-10-11simtech: +CNSMOD value may have multiple digitsAleksander Morgado
We don't expect them in the set of values we support, but they may happen according to the spec.
2019-10-11simtech: add support for reporting LTEAleksander Morgado
2019-10-11simtech: rework access tech value mappingAleksander Morgado
2019-10-11simtech: rework enabling/disabling unsolicited eventsAleksander Morgado
We will explicitly query for +AUTOCSQ and +CNSMOD support before trying to enable them. If +AUTOCSQ is supported and correctly enabled, we'll request signal quality polling to be disabled. If +CNSMOD is supported and correctly enabled, we'll request access technology polling to be disabled.
2019-10-11simtech: enable +CSQ URC supportAleksander Morgado
The +AUTOCSQ setup enables automatic signal quality reporting via +CSQ URCs, which unfortunately have the same format as the +CSQ command responses. Therefore, we need to subclass load_signal_quality() explicitly in order to ignore those cases where the response to the +CSQ command is received empty (already processed as a URC).
2019-10-11simtech: keep access tech URC regex in private structAleksander Morgado
2019-10-11simtech: disable CMER/CIND support explicitlyAleksander Morgado
The logic to setup the generic +CIND indications in the SIM7600E seems to end up breaking connectivity when in TTY+PPP mode. If we issue the AT+CMER=3,0,0,1 command, this will end up in the modem not replying a correct CONNECT response to the ATD command. Let's disable these +CIND indications completely in the simtech plugin, as there is even no AT command reference saying those are supported. Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/144
2019-10-11simtech: implement GPS support with AT+CGPSAleksander Morgado
The new logic is available in a new 'MMSharedSimtech' interface which is implemented both by the generic AT-based MMBroadbandModemSimtech modem, and by a new QMI-based new MMBroadbandModemQmiSimtech. Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/112
2019-10-11simtech: port type hints for the SIM7000/SIM7600 familyAleksander Morgado
E.g. the SIM7600E shows up as: P: Vendor=1e0e ProdID=9001 Rev=03.18 S: Manufacturer=SimTech, Incorporated S: Product=SimTech, Incorporated S: SerialNumber=0123456789ABCDEF C: #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA I: If#=0x0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option I: If#=0x1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
2019-10-11simtech: remove unused ID_MM_SIMTECH_TAGGED tagAleksander Morgado
The plugin already has a VID filter for 0x1e0e, this tag is useless.
2019-09-15simtech: increase +CNSMOD command timeoutAleksander Morgado
From 5s to 20s, as it seems it could take much more to complete and get a response, as seen in the logs below. <debug> [1568553228.546862] (ttyUSB3): --> 'AT+CNSMOD=1<CR>' <debug> [1568553233.799470] (ttyUSB3): --> 'AT+AUTOCSQ=1,1<CR>' <debug> [1568553238.798866] (ttyUSB3) setting up 3GPP unsolicited registration messages handlers <debug> [1568553238.798932] (ttyUSB2) setting up 3GPP unsolicited registration messages handlers <debug> [1568553238.798990] (ttyUSB3) device open count is 1 (close) <warn> [1568553238.799029] (tty/ttyUSB3) at port timed out 2 consecutive times <debug> [1568553238.799094] (ttyUSB3) device open count is 2 (open) <debug> [1568553238.799148] (ttyUSB3): --> 'AT+CREG=2<CR>' <warn> [1568553241.798727] (tty/ttyUSB3) at port timed out 3 consecutive times <debug> [1568553241.798799] (ttyUSB3): --> 'AT+CREG=1<CR>' <debug> [1568553244.795389] Enabling unsolicited registration events in primary port failed: 'AT sequence failed' <debug> [1568553244.795462] (ttyUSB2) device open count is 2 (open) <debug> [1568553244.795507] (ttyUSB3) device open count is 1 (close) <warn> [1568553244.795545] (tty/ttyUSB3) at port timed out 4 consecutive times <debug> [1568553244.795588] (ttyUSB2): --> 'AT+CREG=2<CR>' <debug> [1568553244.800815] (ttyUSB3): <-- '<CR><LF>OK<CR><LF><CR><LF>OK<CR><LF>' <debug> [1568553244.801624] (ttyUSB3): <-- '<CR><LF>OK<CR><LF><CR><LF>OK<CR><LF>' <debug> [1568553244.808710] (ttyUSB2): <-- '<CR><LF>OK<CR><LF>'
2018-08-10base-modem: load AT port type hints when adding portAleksander Morgado
We keep the pflags input in mm_base_modem_grab_port() so that plugins can use other methods to gather port type hints (e.g. querying with AT commands as in Huawei/Telit or looking at sysfs properties as in HSO). For standard udev tag port type hints, it will be the base modem looking them up. Note that there is no longer any need to ignore non-flagged ports for those modems that require primary/secondary flags. They will be implicitly ignored when mm_base_modem_organize_ports() decides which ports to use, as the flagged ones are preferred over the non-flagged ones.
2018-08-10plugins: consolidate ID_MM_PORT_TYPE_AT_* flag namesAleksander Morgado
We define 3 common udev tag ids to be used by all plugins: * ID_MM_PORT_TYPE_AT_PRIMARY: the primary modem port. It will be used for AT control and also as PPP if there is no other port flagged explicitly to do PPP. * ID_MM_PORT_TYPE_AT_SECONDARY: the secondary modem port. It will be used when/if the primary port gets connected to do PPP. * ID_MM_PORT_TYPE_PPP: the port to be used to do PPP only. This tag makes sense only when the primary port shouldn't be used for PPP, i.e. when there is a port dedicated to do PPP and one port dedicated for control.
2018-06-02udev: add tags also on bind actionAleksander Morgado
When a new USB device is hotplugged, e.g. a USB<->RS232 converter that exposes a single ttyUSB0, these udev events happen: add /devices/pci0000:00/0000:00:14.0/usb2/2-1 (usb/usb-device) add /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0 (usb/usb-interface) add /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0/ttyUSB0 (usb-serial) add /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0/ttyUSB0/tty/ttyUSB0 (tty) bind /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0/ttyUSB0 (usb-serial) bind /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0 (usb/usb-interface) bind /devices/pci0000:00/0000:00:14.0/usb2/2-1 (usb/usb-device) Our udev rules in MM only added tags in the 'add' events, and it looks like the only ones 'persistent' after this sequence are those of the last event happening on the specific path. This meant that all TTY subsystem rules (e.g. ID_MM_CANDIDATE) would be stored for later check (e.g. if ModemManager is started after these rules have been applied), which was ok. "udevadm info -p ..." would show these tags correctly always. But this also meant that the 'bind' udev event happening for the USB device didn't get any of our device-specific tags, and so we would be missing them (e.g. ID_MM_DEVICE_MANUAL_SCAN_ONLY) if MM is started after the last event has happened. "udevadm info -p ..." would not show these tags. Modify all our rules to also run at the 'bind' events. See, for context: https://github.com/systemd/systemd/issues/8221
2017-10-07simtech: fix memory leakBen Chan
2017-10-06simtech: port 3gpp_{setup|cleanup}_unsolicited_messages to GTaskAleksander Morgado
2017-10-06simtech: port 3gpp_enable_unsolicited_events to GTaskAleksander Morgado
2017-10-06simtech: port 3gpp_disable_unsolicited_events to GTaskAleksander Morgado
2017-10-06simtech: port load_access_technologies to GTaskAleksander Morgado
2017-10-06simtech: port load_supported_modes to GTaskAleksander Morgado