arsv / minibase Goto Github PK
View Code? Open in Web Editor NEWsmall static userspace tools for Linux
License: GNU General Public License v3.0
small static userspace tools for Linux
License: GNU General Public License v3.0
What is this project ~~~~~~~~~~~~~~~~~~~~ This is a base system / early userspace for Linux. The role of this project in a system is similar to that of busybox in small custom distributions. Boot the system, load modules, mount partitions, establish networking, provide basic services. It is aimed primarily at personal devices running GUIs however. The project builds into small statically-linked executables with no external dependencies. There are no build-time library dependencies either, not even libc. The tools can be built with any toolchain that can build the kernel. Supported targets: x86_64 arm aarch64 rv64 mips mips64 i386. (anything else will not work even if toolchain is available) This project should be mostly useful for people building their own custom systems, distribution, or maybe even just looking for tools to put into initrd. Project status ~~~~~~~~~~~~~~ The project is ONGOING but not yet complete or even stable. Components currently included in the package: * batch command runner / script interpreter (msh) * early-stage boot utils (switchroot, modprobe, mount) * block device locating tools (devinit, findblk) * block device encryption tools (passblk, dektool, deitool) - no fsck for any file system yet * system shutdown tool (reboot) * top-level process supervisor (svchub) * udev event monitor (udevmod) * syslog and related tools (sysklogd) * VT/DRI/input multiplexer (vtmux) and related tools * network interface monitor (ifmon) * Wi-Fi client and connection manager (wsupp) [WPA2-PSK only] * DHCP client (dhconf) * time synchronization (SNTP) service (timed) * manual/static interface setup tools (ip4cfg, ip4info) [incomplete] * simple interactive shell (cmd). * small linux-specific tools (systime, sync, dmesg etc). * application supervisors (apphub, ptyhub) * package management tools (mpac, mpkg, ctool) [incomplete] - no audio tools of any kind. With everything in place, the system should boot on kernel and minibase alone to the point where it can run X or Wayland GUI, establish internet connection and start downloading packages. Quick start ~~~~~~~~~~~ Bootable images for QEMU (buildroot, minibase, Xorg, Weston) along with the build scripts are maintained in a dedicated repository: https://github.com/arsv/minibase-br/ Get the latest sys-plain or sys-crypt from Releases, check included instructions. Inspect the build scripts, rootfs and initrd contents to understand how the system boots. The images there tend to lag behind the master branch here. However, those images should still give a pretty good idea of how the whole thing is supposed to work. How to build and run the tools ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For a proper build, run ./configure make The final target executables will be located in ./bin. To try the tools without setting up a VM, configure and build the project in development mode: ./configure devel make Most tools can be run right from their source directories. Run `make clean` when switching between devel and regular build to force the objects to be rebuilt with the new compiler flags. To build only the tools from a particular directory: make libs make -C src/wsupp This should be run after configure. Just how small exactly? ~~~~~~~~~~~~~~~~~~~~~~~ The largest individual executable so far is `wsupp`, the WPA supplicant. Statically linked for x86_64, it's about 25 KiB in size. Realistically it also needs `dhconf` (12 KiB) to work, and the client tool `wifi` (16 KiB). `msh` is about 16 KiB. `cmd` (interactive shell) is about 18 KiB. `svchub` (pid 1 for the majority of system's uptime) is under 10 KiB. `vtmux` (logind equivalent) is about 12 KiB. Why bother making it small? Because it's a side effect of making it readable and debuggable. The idea is that anyone could pick a tool from minibase, start reading it and gain complete understanding of how it works in a very reasonable amount of time, say hours. And if necessary, audit or debug it down to assembly level. A major point in achieving this is making sure there are no unnecessary wrappers, useless abstractions or dead code, which eventually translates into small executables. Contributing ~~~~~~~~~~~~ This is not a community project. Do not send patches or pull requests. If there's a bug to be fixed, or a tool that you think should be in minibase, or a target to support, open an issue. This will probably change around 1.0 release but not earlier. Licensing ~~~~~~~~~ GNU Public License version 3, see COPYING. Limited closed-box license may or may not get added in the future. The code in lib/sys, lib/bits and lib/arch constitutes the public interface of the Linux kernel. No claims are made for that code, and it should not be copyrightable anyway. If unsure, grab corresponding fragments from either the kernel sources (GPLv2) or the musl libc (MIT license). The code in lib/crypto is mostly BSD-licensed. See README there. Credits ~~~~~~~ Dietlibc and "Writing Small and Fast Software" by Felix von Leitner. https://www.fefe.de/dietlibc/diet.pdf The project was heavily influenced by busybox at early stages. Certain decision from skarnet/s6 project also played significant role. Syscall code (static inline functions with asm volatile blocks) follows musl, because musl folks got it right. The Rust coreutils project provided a great deal of inspiration, specifically by showing how not to write coreutils. See also ~~~~~~~~ https://busybox.net/ http://www.landley.net/toybox/ http://www.fefe.de/embutils/ http://skarnet.org/software/ http://suckless.org http://jdebp.eu/Softwares/nosh/ http://b0llix.net/perp/ http://u-root.tk/ https://swtch.com/plan9port/ https://www.gnu.org/software/coreutils/coreutils.html https://www.kernel.org/pub/linux/utils/util-linux/ https://github.com/uutils/coreutils https://github.com/mit-pdos/xv6-public (userspace tools)
sometimes one simply doesn't have a choice, but has to use what the existing hardware provides. there's still a big percentage of TKIP-only routers out there.
I am connecting from my laptop to the Internet via my phone hotspot. This worked with minibase back in jan/feb this year, but trying now with latest minibase, no joy.
# wifi scan
wifi: scanning device wlan0
AP -53 6b 04:79:70:48:E4:F2 2CC HUAWEINova2x
AP -77 11b 7A:30:D9:A5:25:61 Telstra Air
AP -78 6b 18:90:D8:7A:2D:D2 2CC Telstra7A2DCB
# wifi connect "HUAWEINova2x"
Passphrase: XXXXXXXXX
wifi: no suitable APs
The AP is suitable, so why would wifi be reporting otherwise?
Ha ha, another issue for you!
Yes, ifmon detects if a ethernet cable is plugged in and unplugged, however, it does not detect if the router is turned on or off.
In other words, if the cable is plugged in and router turned off, so no network connection. Then turn on router, now the router has Internet connection, cable is alive, but ifmon does not respond. ifmon does not detect this new situation and does not bring up the network.
'nicmon.c' is a little program that does successfully detect both occurrences, cable plug/unplug and router on/off. Testing, starting with router turn on, cable plugged in:
# ./nicmon2
Turn off router:
Event recieved >> NETLINK::Down
Turn on router:
Event recieved >> Event recieved >> NETLINK::Up
Event recieved >> NETLINK::Down
Event recieved >> NETLINK::Up
Event recieved >> NETLINK::Down
Event recieved >> NETLINK::Up
...above happens in quick succession. ifmon has not detected anything, so has not brought up the Internet.
Unplug cable:
Event recieved >> NETLINK::Down
Plug in cable:
Event recieved >> NETLINK::Up
...and ifmon responds and brings up the Internet.
I did not write nicmon.c, found it somewhere on Internet. Notice that the author may have tried just "addr.nl_groups = RTMGRP_LINK;", then changed it to "addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;".
Anyway, here is the code for nicmon.c, in case you find it useful:
#include <asm/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <net/if.h>
#include <netinet/in.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
int
read_event (int sockint)
{
int status;
int ret = 0;
char buf[4096];
struct iovec iov = { buf, sizeof buf };
struct sockaddr_nl snl;
struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
struct nlmsghdr *h;
struct ifinfomsg *ifi;
status = recvmsg (sockint, &msg, 0);
if (status < 0)
{
/* Socket non-blocking so bail out once we have read everything */
if (errno == EWOULDBLOCK || errno == EAGAIN)
return ret;
/* Anything else is an error */
printf ("read_netlink: Error recvmsg: %d\n", status);
perror ("read_netlink: Error: ");
return status;
}
if (status == 0)
{
printf ("read_netlink: EOF\n");
}
// We need to handle more than one message per 'recvmsg'
for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status);
h = NLMSG_NEXT (h, status))
{
//Finish reading
if (h->nlmsg_type == NLMSG_DONE)
return ret;
// Message is some kind of error
if (h->nlmsg_type == NLMSG_ERROR)
{
printf ("read_netlink: Message is an error - decode TBD\n");
return -1; // Error
}
if (h->nlmsg_type == RTM_NEWLINK)
{
ifi = NLMSG_DATA (h);
printf ("NETLINK::%s\n", (ifi->ifi_flags & IFF_RUNNING) ? "Up" : "Down");
}
}
return ret;
}
int
main (int argc, char *argv[])
{
fd_set rfds, wfds;
//struct timeval tv;
int retval;
struct sockaddr_nl addr;
int nl_socket = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (nl_socket < 0)
{
printf ("Socket Open Error!");
exit (1);
}
memset ((void *) &addr, 0, sizeof (addr));
addr.nl_family = AF_NETLINK;
addr.nl_pid = getpid ();
addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;
// addr.nl_groups = RTMGRP_LINK;
if (bind (nl_socket, (struct sockaddr *) &addr, sizeof (addr)) < 0)
{
printf ("Socket bind failed!");
exit (1);
}
while (1)
{
FD_ZERO (&rfds);
FD_CLR (nl_socket, &rfds);
FD_SET (nl_socket, &rfds);
//tv.tv_sec = 10;
//tv.tv_usec = 0;
//retval = select (FD_SETSIZE, &rfds, NULL, NULL, &tv);
retval = select (FD_SETSIZE, &rfds, NULL, NULL, NULL); //wait forever.
if (retval == -1)
printf ("Error select() \n");
else if (retval)
{
printf ("Event recieved >> ");
read_event (nl_socket);
}
else //0=timed-out, should not happen.
printf ("## Select TimedOut ## \n");
}
return 0;
}
Hi, I am trying to understand how the networking utilities work.
Using latest minibase source from github (2019-02-4), reading net2/README, it refers to 'ipcfg'. However, that has been removed.
What did it do, and what replaces it?
Also, I have not understood how profiles get created. Perhaps it doesn't help that I am reading the net2/README file, which pertains to the older utilities!
I see that there is "ifctl eth0 mode lan", but where would that get called?
Well, I did this:
# ifmon
+++ identify eth0
+++ identify eth1
+++ identify wlan0
...but don't know where to go from there. I have eth0, and all that I would normally do is bring it up and run the dhcp client:
# ifconfig eth0 up
# dhcpcd eth0
I did create /etc/net/mode-lan0, with this:
#!/bin/sh
echo "+++ mode-lan0 $1"
ifctl $1 auto-dhcp
But that doesn't get called, so obviously I have not assigned "lan0" as profile to eth0.
Any advice greatly appreciated, and excuse me if I have been incredibly dumb not understanding something obvious!
cancelled
The DRM video driver of my machine has no GPU driver, so, wayland/weston does not accept the drm-backend (with this strange message: No available targets are compatible with this triple.). So, I use the fbdev-backend.
Starting weston from vtmux works fine, but, the keyboard characters are sent to both weston and the underlaying VT console. Indeed, when the VT cursor reaches the bottom of the screen, a scroll occurs and all the characters of the console are displayed over the wayland screen.
Is there a way to avoid this problem?
Hi, would you mind commenting on what the practical effect is of this commit:
I haven't understood what the effect will be of the change, how does it affect behaviour of dhcp?
wsupp logs this:
wsupp: exec /etc/net/wifi-wpa: ENOENT
"ENOENT" means "no such file or directory", however, it does exist, and is executable.
Why is this happening?
This morning I was examining the unique-ID mechanism, and realised that the inability to obtain such for USB devices compromises the usability of the method.
USB devices have vendor-id and product-id, also a serial-number. However, there is no guarantee of uniqueness.
What is needed is for each network device to have a unique ID. Well, they do, the MAC address.
No need to be concerned about the pci path, to assign a unique ID, use the MAC address. It is easy to obtain. It can be done with various utilities, such as:
# ip link show wlan0
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000
link/ether 1c:4d:70:3c:e6:91 brd ff:ff:ff:ff:ff:ff
Or, read it directly in /sys:
# cat /sys/class/net/wlan0/address
1c:4d:70:3c:e6:91
Hi, the ifmon manpage refers to spawning /etc/net/conf-cancel, however, I cannot find it in the source code.
There is conf-release, so I presume that is what is intended.
If I plug in a ethernet cable, conf-request is called. Fine, but unplugging the cable does nothing. Neither conf-cancel nor conf-release are called.
I changed this line in /etc/net/mode-lan0, thinking that is needed to recognize cable being unplugged:
#ifctl $1 auto-dhcp
ifctl $1 dhcp-once
But no, makes no difference.
Have I missed understanding something?
Hi,
Your project seems very interesting for small machines, but I fell on some problems. Here are the easier ones to fix.
First, 'cc -dumpmachine' returns "armv7l-linux-gnueabihf", doing ./configure to abort.
Then, I had problems when setting the groups in the /etc/vtmux/tty scripts for X11 and Wayland. The .config of my kernel contains "CONFIG_UID16=y", and this makes the system to have 2 sets 16 and 32 bits for the system calls getgroups, setgroups, getresuid and getresgid. The same problem also exists for i386 machines.
My traditional thinking, to start and stop 'ifmon' and 'wsupp', might be something like /etc/init.d/minibase-net:
#!/bin/sh
case "$1" in
start)
mkdir -p /run/ctrl
#note, the full start-stop-daemon from dpkg is required (not busybox applet)...
#-S start, -b background, -C do not close fd, -x execute
start-stop-daemon -S -b -C -x /sbin/ifmon >> /var/log/ifmon.log 2>&1
start-stop-daemon -S -b -C -x /sbin/wsupp >> /var/log/wsupp.log 2>&1
;;
stop)
#-K kill
start-stop-daemon -K -x /sbin/wsupp
start-stop-daemon -K -x /sbin/ifmon
;;
esac
However, as 'ifmon' and 'wsupp' do recognise if already running, that is one less reason to use 'start-stop-daemon'. They don't background themselves, but that could be achieved by appending "&", so perhaps this would suffice:
#!/bin/sh
case "$1" in
start)
mkdir -p /run/ctrl
ifmon >> /var/log/ifmon.log 2>&1 &
wsupp >> /var/log/wsupp.log 2>&1 &
;;
stop)
killall ifmon
killall wsupp
;;
esac
Do you have any thoughts about the correct way to do this? Also, for a generic shutdown, would it be appropriate to do anything else before killing ifmon and wsupp? -- I do understand that perhaps bringing down the "up" interfaces would be appropriate.
I also realise that I am taking these utilities out of context. They are intended to work in minibase, with its own process manager.
hi! i'm really impressed by wsupp and would like to embed it into my musl-based distro sabotage linux because wpa_supplicant drives me crazy.
however, i want it to use vanilla musl libc so it's portable to any linux arch, not just the ones in your mini-libc. also, i would like to keep using the familiar tools ifconfig etc from busybox.
i do think that using musl would not make the binary considerably bigger, and opens the tool to a much bigger audience.
would you be willing to make such a portable version ?
btw, our approach to handling the dhclient / static IP stuff after connection is by calling an external script which creates a background task (so as not to block) and calls itself again.
https://github.com/sabotage-linux/sabotage/blob/master/KEEP/wpa_supplicant-action_script.patch
https://github.com/sabotage-linux/sabotage/blob/master/KEEP/etc/wpa_connect_action.sh#L33
i use the essid in the script to set different static ip or dhcp rule according to network name.
As vtmux locks the VT switching mechanism, the X server hangs when it wants to switch to the graphic VT. Calling 'unlock' in the /etc/vtmux/tty X11 script resolves this problem.
But a new problem is raised when switching from X11 to a vtmux console and back to X11: the graphic VT is not reachable but with the legacy switch (unlock).
What did I miss?
EasyOS is compiled from source. I have it running on x86_64 PCs and on RPi3 and Rock64 aarch64 boards. No problem compiling minibase on x86_64, but on the Rock64 board, got this error:
make[2]: Entering directory '/mnt/sda1/work11/minibase-20190218-p1/lib/util'
../../mini-cc -c argbits.c
../../mini-cc -c basename.c
../../mini-cc -c errlist.c
../../mini-cc -c execvp.c
../../mini-cc -c fail.c
In file included from fail.c:1:0:
../../lib/sys/file.h:124:0: warning: "NR_fstatat" redefined
# define NR_fstatat NR_fstatat64
In file included from ../../lib/arch/aarch64/syscall.h:4:0,
from ../../lib/sys/file.h:1,
from fail.c:1:
../../lib/arch/aarch64/bits/syscall.h:83:0: note: this is the location of the previous definition
#define NR_fstatat 79
In file included from fail.c:1:0:
../../lib/sys/file.h: In function ‘sys_stat’:
../../lib/sys/file.h:124:21: error: ‘NR_fstatat64’ undeclared (first use in this function)
# define NR_fstatat NR_fstatat64
^
../../lib/sys/file.h:129:18: note: in expansion of macro ‘NR_fstatat’
return syscall4(NR_fstatat, AT_FDCWD, (long)path, (long)st, 0);
^~~~~~~~~~
../../lib/sys/file.h:124:21: note: each undeclared identifier is reported only once for each function it appears in
# define NR_fstatat NR_fstatat64
^
../../lib/sys/file.h:129:18: note: in expansion of macro ‘NR_fstatat’
return syscall4(NR_fstatat, AT_FDCWD, (long)path, (long)st, 0);
^~~~~~~~~~
../../lib/sys/file.h: In function ‘sys_fstatat’:
../../lib/sys/file.h:124:21: error: ‘NR_fstatat64’ undeclared (first use in this function)
# define NR_fstatat NR_fstatat64
^
../../lib/sys/file.h:144:18: note: in expansion of macro ‘NR_fstatat’
return syscall4(NR_fstatat, dirfd, (long)path, (long)st, flags);
^~~~~~~~~~
../../lib/sys/file.h: In function ‘sys_lstat’:
../../lib/sys/file.h:124:21: error: ‘NR_fstatat64’ undeclared (first use in this function)
# define NR_fstatat NR_fstatat64
^
../../lib/sys/file.h:149:18: note: in expansion of macro ‘NR_fstatat’
return syscall4(NR_fstatat, AT_FDCWD, (long)path, (long)st,
^~~~~~~~~~
make[2]: *** [../rules.mk:13: fail.o] Error 1
make[2]: Leaving directory '/mnt/sda1/work11/minibase-20190218-p1/lib/util'
make[1]: *** [Makefile:69: build-util] Error 2
make[1]: Leaving directory '/mnt/sda1/work11/minibase-20190218-p1/lib'
make: *** [Makefile:14: lib/all.a] Error 2
I commented-out from line 121 in minibase/lib/sys/file.h:
/*#ifdef NR_newfstatat
# define NR_fstatat NR_newfstatat
#else
# define NR_fstatat NR_fstatat64
#endif*/
And it compiled.
Hi, I am creating a little GUI for the minibase net utilities, using gtkdialog.
For wifi, it displays the SSIDs, and has a password entry box and a "Connect" button.
The SSIDs are radiobuttons, and if the use chooses one, I would like it if can determine whether a password has already been provided -- if so, will grey-out the password box.
Is there any way to determine if password already applied to a particular SSID?
Hi, I think that I have understood the basics of how ifmon, ifctl, etc. work.
It seems that ifmon is somewhat restricted in its capabilities. The man page states:
Network interfaces in Linux are not static and cannot be reliably configured during system startup. ifmon addresses this problem by monitoring kernel events and spawning scripts to configure interfaces once they appear in the system.
However, I don't think that is the main problem. For most users, the network interfaces are static. What changes is their usability. If the ethernet cable is not plugged in, or the router turned off, the interface is not "live" and unusable.
This "aliveness" is monitored by daemons such as 'networkmamager' and 'ifplugd', and they can automatically respond to a interface becoming alive, or the reverse.
One could also create a polling loop, running 'ethtool' or 'ifplugstatus' to test for aliveness.
In Puppy Linux, for example, there is a startup script that runs 'ifplugstatus' on each of the found ethernet interfaces, if one is found to be live, 'dhcpcd' is run on that interface.
With 'ethtool' you can do something like this:
ethtool "$INTERFACE" | grep -Fq 'Link detected: yes'
I don't know if there is any simple way this can be determined by looking in /sys
Alex, hi, I am coming back to look at minibase after some time. Looking at dhconf, I am unclear how it replaces dhcp. Would you mind saying a few words about this?
I was familiar with running "dhcp $IF request", "dhcp $IF cancel", etc., so are these operations no longer required? Is dhconf now something that is totally automatic, nothing to put in any scripts?
Trying the scripts that I was using back in jan/feb. This one does not work:
#!/bin/sh
#assigns a persistent interface to a script.
echo "+++ identify $1"
IF="$1"
IDflg=""; NET='lan'
[ -d /sys/class/net/${IF}/wireless ] && NET='wifi'
if [ -s /var/local/interfaces ];then
IDflg="$(ifctl | grep "${IF} mode ${NET}")"
fi
#if not, assign it...
if [ "$IDflg" == "" ];then
NUM="${IF/*[a-z]/}"
if [ ! -f /etc/net/mode-${NET}${NUM} ];then
cp -a /etc/net/mode-${NET} /etc/net/mode-${NET}${NUM}
fi
ifctl ${IF} mode ${NET}${NUM}
fi
echo " executing: ifctl $IF identify"
ifctl $IF identify
###end###
Whether I should be still doing this is a different question. The question right now, is that running IDflg="$(ifctl | grep "${IF} mode ${NET}")"
used to return assigned profile, such as "wlan0: mode wifi0". Now, running ifctl within /etc/net/identify only returns "wlan0, running identify"
is this deliberate, that mode information is no longer displayed at this stage?
As the script has nothing in IDflg, it executes ifctl ${IF} mode ${NET}${NUM}
, and this hangs, does not return. It should not be executed, as the profile has already been assigned, but it should not hang.
From a terminal, I can type ifctl wlan0 mode wifi0
and it correctly informs me that the profile is already assigned. Is it deliberate that this cannot be run from within the identify script?
I like your approach of network connections, but I could not make it work for WIFI.
While network scanning works fine, on wifi connect, the process hangs. The traces show that wsupp sends an authenticate message to the WIFI driver, but this one never answers.
I do not know enough about WIFI to understand the reason of the socket switch, but, could there be some problem there?
I have now got onto exploring wifi. Yes, works, but...
# wifi
AP -49 6b 2CC HUAWEINova2
AP -59 13b 2CC Telstra7A2DCB
Device wlan1 idle
# wifi scan
AP -51 6b 2CC HUAWEINova2
AP -63 13b 2CC Telstra7A2DCB
# wifi connect HUAWEINova2
Passphrase: XXXXXXXXXX
wifi: connected to AP HUAWEINova2 (6b/2437MHz)
# wifi detach
# wifi
wifi: service inactive
# wifi device wlan1
# wifi
AP -55 6b 2CC HUAWEINova2
AP -63 13b 2CC Telstra7A2DCB
Device wlan1 idle
#
Yes, it works. As you can see above, I ran "wifi detach". If I now wait about 15 minutes and try again:
# wifi scan
AP -53 6b 2CC HUAWEINova2
AP -65 13b 2CC Telstra7A2DCB
# wifi connect HUAWEINova2
...hung. in another terminal:
# wifi
AP -53 6b 2CC HUAWEINova2
AP -65 13b 2CC Telstra7A2DCB
Waiting for AP HUAWEINova2 (6b/2437MHz)
#
wsupp is now unresponsive, cannot detach, even killing it and restarting, still cannot obtain the AP.
What is happening here is something to do with my phone. I am using it as a hotspot, and an AP can only be obtained very soon after the hotspot is activated on the phone. After so many minutes (don't know exactly how long, but I waited for 15 minutes above), the AP can no longer be obtained.
wpa_supplicant has the same problem, which is one reason why I am investigating alternatives. Yet, Windows 10 has absolutely no problem with getting the AP.
Someone suggested that the phone might go into some kind of low-power mode sometime after the hotspot is brought up. However, Win10 has no problem with obtaining the AP, no matter how long the phone has been sitting there without any clients connected to the hotspot.
So, what does Win10 do to "wake up" the phone? Or whatever.
One other thing, with wpa_supplicant, if I turn off the hotspot on the phone then back on, wpa_supplicant then succeeds. But not wsupp, it is stuck waiting forever.
Any thoughts?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.