Puppy In-House Development

Under development: PCMCIA, wireless, etc.
Message
Author
User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#271 Post by technosaurus »

Sorry about that. I assumed it wouldn't patch cleanly but it looked to me that there were only a relatively few number of changes to be manually patched ... adding evdev.c and modifying some lines in kdrive/linux/* Should I use Isaacs's branch or Dima's to have a blind stab at it?

here is the player: haven't toyboxed the mixer yet (just trying to get enough to test sound in aboriginal builds, so will need the mixer to ensure volume is audible)

Code: Select all

/* wav.c - Plays wav file(s).
 *
 * Copyright 2014 Brad Conroy <bconroy@uis.edu>
 *
 * See https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

USE_WAV(NEWTOY(wav, "<1", TOYFLAG_BIN))

config WAV
  bool "wav"
  default n
  help
   usage: wav [wav file...]

   Plays wav files.
*/

#define FOR_wav
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/soundcard.h>
#include "toys.h"

void do_wav(int fd, char *name){

  struct {
    char      ChunkID[4]; // "RIFF"
    uint32_t  ChunkSize;
    char      Format[4]; // "WAVE"
    char      Subchunk1ID[4]; // "fmt "
    uint32_t  Subchunk1Size;
    uint16_t  AudioFormat; //1
    uint16_t  NumChannels; //1==mono, 2==stereo
    uint32_t  SampleRate; //8000, 44100,...
    uint32_t  ByteRate;
    uint16_t  BlockAlign;
    uint16_t  BitsPerSample;
    char      Subchunk2ID[4]; //0x64617461 "data"
    uint32_t  Subchunk2Size;
  } *hdr = (void *) &toybuf; //to save 44 bytes

  read(fd,hdr,44);
  if (
    memcmp(hdr->ChunkID,"RIFF",4)     ||
    memcmp(hdr->Format,"WAVE",4)      ||
    memcmp(hdr->Subchunk1ID,"fmt ",4) ||
    memcmp(hdr->Subchunk2ID,"data",4) ||
    (1 != hdr->AudioFormat) //or mulaw, alaw, ima-adpcm?
  ) return;
#if !IS_LITTLE_ENDIAN
  bswap_32(hdr->SampleRate);
  bswap_16(hdr->NumChannels);
  bswap_16(hdr->BitsPerSample); 
#endif
  int value, dsp=open("/dev/dsp",O_WRONLY);
  if (dsp<0) return;
  value=hdr->NumChannels;
  xioctl(dsp, SNDCTL_DSP_CHANNELS, &value);
  value=hdr->SampleRate;
  xioctl(dsp, SNDCTL_DSP_SPEED, &value);
  value=hdr->BitsPerSample;
  xioctl(dsp, SNDCTL_DSP_SETFMT, &value);
  while ((value=readall(fd,toybuf,sizeof(toybuf))))
    writeall(dsp,toybuf,value);
  close(dsp);
}

void wav_main(void){
  loopfiles(toys.optargs, do_wav);
}
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
Iguleder
Posts: 2026
Joined: Tue 11 Aug 2009, 09:36
Location: Israel, somewhere in the beautiful desert
Contact:

#272 Post by Iguleder »

I think tinyxserver isn't worth the effort. It's too old and limited - evdev support is a minor problem compared to other deal breakers (e.g the lack of GTK+ 2.x support).

Ideally, I'd like to have working Xlib and Xfbdev/Xvesa in one sources tree, with makefiles, without redundant BSD/Windows/whatever code, support for cross-compilation and a -DTINY flag which disables big, unneeded features.

I really like Tiny Core's tinyx - they just stripped X.Org 1.2. However, you still need X.Org's protocol headers and libraries, so it kinda misses the point. It takes ages to build and maintaining so many small packages is a big burden.
[url=http://dimakrasner.com/]My homepage[/url]
[url=https://github.com/dimkr]My GitHub profile[/url]

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#273 Post by technosaurus »

I can try to revert the xvesa removal from mainline and have patches that remove bulky non-features... replace the static table based builtin iconv for at least the large asian locales with system iconv calls (or all of them? Leaving it up to iconv whether to use static tables ... just removing support for builtin large asian locales reduces x11 to ~850k and I already made a patch for that)

I also have a preliminary toybox mixer (improved) that I will post soon... feel free to scrape it for coding a tiny alsa version for dslr.

Edit:
Here is my working copy of mix.c - I had to make a sudden trip out of town for a funeral and forgot my linux flash drives (posting from win7 -yuk). It was pretty close to working IIRC, so give it a try if you wish.

Code: Select all

/* mix.c - A very basic mixer.
 *
 * Copyright 2014 Brad Conroy, dedicated to the Public Domain.
 *

USE_MIX(NEWTOY(mix, "m:d:l#r#", TOYFLAG_USR|TOYFLAG_BIN))
config MIX
  bool "mix"
  default n
  help
   usage: mix [-m mixer] [-d device] [-l level / left level] [-r right level]

   Lists/sets mixer devices/levels.
*/

#define FOR_mix
#include <linux/soundcard.h>
#include "toys.h"


GLOBALS(
   char *mixer;
   char *device;
   int level;
   int right;
)

void mix_main(void)
{

  const char *devices[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
  char *mixer_name=(toys.optflags & FLAG_m)?TT.mixer:"/dev/mixer";
  int i, mask, device=-1, level, mixer=xopen(mixer_name, O_RDWR|O_NONBLOCK);

  xioctl(mixer, SOUND_MIXER_READ_DEVMASK,&mask);

  if (!(toys.optflags & FLAG_d)){
    for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i)
      if (1<<i & mask) printf("%s\n",devices[i]);
    return;
  }else{
    for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i){
      if (!strcmp(devices[i], TT.device)){
        if (1<<i & mask) device=i;
        else return; //with error
        break;
      }
    }
  }

  if (-1==device)
    return; //with error

  if (!(toys.optflags & FLAG_l)){
    xioctl(mixer, MIXER_READ(device),&level);
    printf("%s:%s = %d\n",mixer_name,devices[device],level);
    //todo - handle left and right channels w/ bitops. if (level&0xff00)...
    return;
  }

  level=TT.level;
  if (!(toys.optflags & FLAG_r))
    level = TT.right | (level<<8);

  xioctl(mixer, MIXER_WRITE(device),&level);
  close(mixer);
}
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
Iguleder
Posts: 2026
Joined: Tue 11 Aug 2009, 09:36
Location: Israel, somewhere in the beautiful desert
Contact:

#274 Post by Iguleder »

Mouse scrolling works in tinyxserver!

I decided to see how DSL behaves - somehow, it doesn't recognize the Super keys, like tinyxserver, but mouse scrolling works. I couldn't find DSL's source code to see why. Its changelogs mention some patch that made mouse scrolling work, but I couldn't find any trace of it, in both DSL's stuff and X.Org's git.

I took a look at complaints of DSL users about mouse issues - in one of them, I saw a suggestion to run the X server with "-mouse /dev/psaux,5". I knew 5 means 5 buttons, after reading so much ugly X server code, so I grepped tinyxserver's code for mouse\". I found it in hw/kdrive/kdrive.c - there's a function that accepts this string and parses it. If you look closely enough, you'll see a variable which specifies the number of buttons - the default is 3.

I just changed the default to 5, since pretty much all mice have a scroll wheel these days. Now, when you run tinyxserver without any options, it uses the first mouse it finds and assumes it has a scroll wheel. Perfect :D
[url=http://dimakrasner.com/]My homepage[/url]
[url=https://github.com/dimkr]My GitHub profile[/url]

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#275 Post by Ibidem »

technosaurus wrote: Edit:
Here is my working copy of mix.c - I had to make a sudden trip out of town for a funeral and forgot my linux flash drives (posting from win7 -yuk). It was pretty close to working IIRC, so give it a try if you wish.

Code: Select all

/* mix.c - A very basic mixer.
 *
 * Copyright 2014 Brad Conroy, dedicated to the Public Domain.
 *

USE_MIX(NEWTOY(mix, "m:d:l#r#", TOYFLAG_USR|TOYFLAG_BIN))
config MIX
  bool "mix"
  default n
  help
   usage: mix [-m mixer] [-d device] [-l level / left level] [-r right level]

   Lists/sets mixer devices/levels.
*/

#define FOR_mix
#include <linux/soundcard.h>
#include "toys.h"


GLOBALS(
   char *mixer;
   char *device;
   int level;
   int right;
)

void mix_main(void)
{

  const char *devices[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
  char *mixer_name=(toys.optflags & FLAG_m)?TT.mixer:"/dev/mixer";
  int i, mask, device=-1, level, mixer=xopen(mixer_name, O_RDWR|O_NONBLOCK);

  xioctl(mixer, SOUND_MIXER_READ_DEVMASK,&mask);

  if (!(toys.optflags & FLAG_d)){
    for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i)
      if (1<<i & mask) printf("%s\n",devices[i]);
    return;
  }else{
    for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i){
      if (!strcmp(devices[i], TT.device)){
        if (1<<i & mask) device=i;
        else return; //with error
        break;
      }
    }
  }

  if (-1==device)
    return; //with error

  if (!(toys.optflags & FLAG_l)){
    xioctl(mixer, MIXER_READ(device),&level);
    printf("%s:%s = %d\n",mixer_name,devices[device],level);
    //todo - handle left and right channels w/ bitops. if (level&0xff00)...
    return;
  }

  level=TT.level;
  if (!(toys.optflags & FLAG_r))
    level = TT.right | (level<<8);

  xioctl(mixer, MIXER_WRITE(device),&level);
  close(mixer);
}
Big issue is that GLOBALS() must be in the reverse order of the NEWTOY optstring, which makes for a segfault if -d is passed.
You can drop char *mixer_name and instead do:

Code: Select all

  int mixer = xopen(TT.mixer?TT.mixer:"/dev/mixer", O_RDWR | O_NONBLOCK);
(make sure to give mixer its own line, even if you don't add a separate "int" declaration.)
The "else return" in the loop can go; it catches a strict subset of cases of "if (-1==device) return;" because the break statement would leave the loop with device still set to -1.
Properly all the ints in GLOBALS() should be longs.
And I thought that the mixer ioctls took a (unsigned?) short not an int, which could explain why I can't get this to reset vol on my system...

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#276 Post by technosaurus »

Ibidem wrote: (make sure to give mixer its own line, even if you don't add a separate "int" declaration.)
The "else return" in the loop can go; it catches a strict subset of cases of "if (-1==device) return;" because the break statement would leave the loop with device still set to -1.
Properly all the ints in GLOBALS() should be longs.
And I thought that the mixer ioctls took a (unsigned?) short not an int, which could explain why I can't get this to reset vol on my system...
Thanks for the pointers. I still don't have the toybox inner workings down and still learning ioctl() (its powerful and applies to all sorts of interfaces but not well documented outside the kernel source).
I was hoping the int vs short wouldn't make a difference so long as the values were withing the short range, but I continue to learn new stuff about C all the time. Even after I think I have got my code pretty damn good, Rob ends up doing a cleanup pass that makes me blush.

I wonder if we could maintain extra toys that are not a good fit for standard toybox in an toys/extras directory, the build system already does toys/*/*.c, so having an extra directory of sane-but-non-standard tools would be fairly simple, but I'd like to look into the mechanism for adding $extralibs for things like tinyx11 or eventually xcb. I'd like to do xvesa/xfbdev, a terminal emulator and a window manager at a minimum (enough to get to a working "desktop")

Would anyone be interested in using goingnut's (permissively licensensed) mazewm to replace jwm and possibly adding support for stb_img and maybe libsvgtiny (from netsurf)??? Another route would be to have separate/interchangeable xcb based apps for window manager, pager, menu, deskop, tray, etc... mcwm is a good starting point for that path and the dwm/i3 projects have much of the rest.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#277 Post by technosaurus »

mix is working:

Code: Select all

/* mix.c - A very basic mixer.
 *
 * Copyright 2014 Brad Conroy, dedicated to the Public Domain.
 *

USE_MIX(NEWTOY(mix, "m:d:l#r#", TOYFLAG_USR|TOYFLAG_BIN))
config MIX
  bool "mix"
  default n
  help
   usage: mix [-m mixer] [-d device] [-l level / left level] [-r right level]

   Lists/sets mixer devices/levels.
*/

#define FOR_mix
#include <linux/soundcard.h>
#include "toys.h"


GLOBALS(
   int right;
   int level;
   char *device;
   char *mixer;
)

void mix_main(void)
{
  const char *devices[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
  char *mixer_name=(toys.optflags & FLAG_m)?TT.mixer:"/dev/mixer";
  int i, mask, device=-1, level,
      mixer=xopen(mixer_name, O_RDWR|O_NONBLOCK);

  xioctl(mixer, SOUND_MIXER_READ_DEVMASK,&mask);

  if (!(toys.optflags & FLAG_d)){
    for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i)
      if (1<<i & mask) printf("%s\n",devices[i]);
    return;
  }else{
    for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i){
      if ((1<<i & mask) && !strcmp(devices[i], TT.device)){
        device=i;
        break;
      }
    }
    if (-1==device) return; //with error
  }

  if (!(toys.optflags & FLAG_l)){
    xioctl(mixer, MIXER_READ(device),&level);
    if (0xFF < level) printf("%s:%s = left:%d\t right:%d\n", mixer_name,
                             devices[device], level>>8, level & 0xFF);
    else printf("%s:%s = %d\n",mixer_name, devices[device], level);
    return;
  }

  level=TT.level;
  if (toys.optflags & FLAG_r) level = TT.right | (level<<8);

  xioctl(mixer, MIXER_WRITE(device),&level);
  close(mixer);
}
Edit: fixed wrong ! on FLAG_r test
Last edited by technosaurus on Thu 31 Jul 2014, 02:13, edited 1 time in total.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#278 Post by Ibidem »

It only sets vol for me if I pass -r and -l.
...
I think this line is wrong:

Code: Select all

if (!(toys.optflags & FLAG_r)) level = TT.right | (level<<8);
That means:
If only -l was passed (and TT.right is 0), set level to level<<8.

So, a question about the ioctl:
Does 100<<8 set left channel or right channel to 100?

Experimenting, I find that removing the negation of the test makes it work more as I expected.
Also, the test for whether to set or show should be "& (FLAG_l | FLAG_r)"

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#279 Post by Ibidem »

On a completely unrelated note, I finally put my "wpanet" service on github (under CC0).
http://github.com/idunham/wpanet
It just starts wpa_supplicant and wpa_cli, and uses the second to start dhcp at the right time.
I find that it works well for connecting to wireless (including how it handles flakey connections).

But it does not have any tools for configuration, especially for setting up the first wpa_supplicant.conf. If someone wants to write one, I'd appreciate it...as long as they don't add too much bloat.
As far as dependencies go:
not python, not perl; some versions I can think of include: Tcl/Tk, bash/ksh with select, sh with dialog/xdialog/?whiptail, or sh with gtkdialog[123].
A C frontend is also acceptable, if it doesn't drag in too many libraries.
The minimum functionality that would be needed is:
-Create new config file (with ctrl_interface=/var/run/wpa_supplicant )
-View networks (wpa_cli scan_results)
-Add network (from the list of scan results or otherwise; support open/wep/wpa)
-disconnect/reassociate
All of these except 1. can be done from wpa_cli.

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#280 Post by technosaurus »

Ibidem wrote:It only sets vol for me if I pass -r and -l.
...
I think this line is wrong:

Code: Select all

if (!(toys.optflags & FLAG_r)) level = TT.right | (level<<8);
That means:
If only -l was passed (and TT.right is 0), set level to level<<8.

So, a question about the ioctl:
Does 100<<8 set left channel or right channel to 100?

Experimenting, I find that removing the negation of the test makes it work more as I expected.
Also, the test for whether to set or show should be "& (FLAG_l | FLAG_r)"
Here is the rundown as I understand it:
Some devices don't have a left and right channel, for those (or if you want to set both channels with a precalculated short value) the -l flag means "level" vs "left" in the absence of a -r

If the -r flag _is_ passed (yes the `!` was probably an oversight, its not in my local version - will edit my post) the the -l means left channel which is the MSByte of a short and the -r value is the right channel which is the least significant byte of a short (thus the bitwise shift by 8 and the OR).
Although the values are short, Linux syscalls always take and return longs whether it be a pointer, integer type, or string ... the conversion is handled by the libc (I have a working syscall implementation if you want to see how it works)

The flag -r should not be passed without -l, so the (FLAG_l | FLAG_r) ... unless I add another option for just value such that -l always sets the MSB and -r always sets the LSB if passed individually and the -v (or whatever) sets the entire value from 0 to max unsigned long which could work for setting l and r simultaneously or to workaround strange behaviors one might encounter - currently this is how -l without a -r is supposed to work.

... need to see if
a) toybox already has a way to dissallow one flag without the other
b) use the existing value to allow changing only -r or -l like:???
- -l: level = (level & 0xFF) | (TT.level<<8)
-r: level = (level & 0xFF00) | (TT.right)
-v: level = TT.value
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#281 Post by technosaurus »

Ibidem wrote:On a completely unrelated note, I finally put my "wpanet" service on github (under CC0).
http://github.com/idunham/wpanet
It just starts wpa_supplicant and wpa_cli, and uses the second to start dhcp at the right time.
I find that it works well for connecting to wireless (including how it handles flakey connections).

But it does not have any tools for configuration, especially for setting up the first wpa_supplicant.conf. If someone wants to write one, I'd appreciate it...as long as they don't add too much bloat.
As far as dependencies go:
not python, not perl; some versions I can think of include: Tcl/Tk, bash/ksh with select, sh with dialog/xdialog/?whiptail, or sh with gtkdialog[123].
A C frontend is also acceptable, if it doesn't drag in too many libraries.
The minimum functionality that would be needed is:
-Create new config file (with ctrl_interface=/var/run/wpa_supplicant )
-View networks (wpa_cli scan_results)
-Add network (from the list of scan results or otherwise; support open/wep/wpa)
-disconnect/reassociate
All of these except 1. can be done from wpa_cli.
Feel free to totally disagree with me, but I always felt like configuration guis, especially those associated with internet connection would be best suited to a web interface (axhttpd or busybox httpd + shell cgi for example) This would allow us to modify the "no internet access" webpage to redirect to localhost/cgi-bin/config-network.cgi ... I wrote a bunch of helpers for creating html forms that can be used with cgi scripts in my old bashbox thread that could be used for this.... and even some menus, draggable icons and "windows" that were intended for a web desktop (see web programming thread) ... but the config pages would just be forms that will work with any forms capable browser including links (using css to make them look "pretty" in supporting browsers) for security purposes use .htaccess to allow only localhost connections and chmod extra config files so only the httpd process has access (for instance a file with the WPA password(s) for auto config could be placed there by root or the cgi script itself) I realize it is yet another process running in the background, but it is small and has many other uses.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#282 Post by Ibidem »

technosaurus wrote:Although the values are short, Linux syscalls always take and return longs whether it be a pointer, integer type, or string ... the conversion is handled by the libc (I have a working syscall implementation if you want to see how it works)

The flag -r should not be passed without -l, so the (FLAG_l | FLAG_r) ... unless I add another option for just value such that -l always sets the MSB and -r always sets the LSB if passed individually and the -v (or whatever) sets the entire value from 0 to max unsigned long which could work for setting l and r simultaneously or to workaround strange behaviors one might encounter - currently this is how -l without a -r is supposed to work.
I have an odd builtin microphone that needs to have one channel set to ~mute for it to work, so setting -r without -l is meaningful...
(Yes, treating this as an implied -l 0 is OK.)
... need to see if
a) toybox already has a way to dissallow one flag without the other
b) use the existing value to allow changing only -r or -l like:???
- -l: level = (level & 0xFF) | (TT.level<<8)
-r: level = (level & 0xFF00) | (TT.right)
-v: level = TT.value
Regarding (a), there are ways to make one flag imply, unset, or forbid anther. See code.html, section [groups].

Speaking of that, l#r# should probably be "l#<0>100r#<0>100", since (as far as I know) a channel's volume must be no more than 100 nor less than 0.

Regarding a CGI interface for wpanet: I have no objection to a CGI interface, so long as it is not intended to exclude all others. I'm inclined to think that one text mode UI, at least one graphical UI, and a CGI interface would be nice ;)
But my experience with anything http-related consists of getting http://myweb.csuchico.edu/~idunham/ set up, so I certainly don't want to write the CGI part.

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#283 Post by technosaurus »

Ibidem wrote:Speaking of that, l#r# should probably be "l#<0>100r#<0>100", since (as far as I know) a channel's volume must be no more than 100 nor less than 0.
You would hope so, but who knows what vendor implemented a "This one goes to 11." mode. As it is -l should be limited to 65536 when no -r flag is present and -r should be limited to 256 (and -l when -r is present) ... I'm thinking:
v#<0>65536 ... is there a better/standard letter to use than v?, possibly any argument without a flag?
r#<0>256
l#<0>256

If you can write shell scripts, cgi is easy - all you have to do is parse the $QUERY_STRING environment variable in ?var=value&var2=value2 format as you would normally use $1, $2. That can be as simple as:

Code: Select all

IFS="?&"
for PAIR in $QUERY_STRING;do
case $PAIR in
  var=*)VAR=${PAIR#*=} #do stuff with $VAR
  ;;
  var2=*): handle var2;;
  *): handle error;;
esac
#reset IFS
The rest is just html and http headers - where only Content-length: changes
For Content-length: field I keep the whole page in a variable HTML and use:
Content-length: ${#HTML}
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#284 Post by technosaurus »

Ibidem wrote:I have an odd builtin microphone that needs to have one channel set to ~mute for it to work, so setting -r without -l is meaningful...
(Yes, treating this as an implied -l 0 is OK.)
-l 100 without -r sets the _level_ (not left) to 100 which is the same as -l 0 -r 100 (if -r is not given, this level will be the right channel if there are 2 channels and the left will be 0, but -l is intended to be used on mono/single level systems) ... to set left to 100 and right to zero you would need -l 100 -r 0 ... not sure the best way to convey this in --help but -l alone is overall level for the whole device, and you should use -l in combination with -r with explicitly set values for setting individual channels ... perhaps allow #<-1>100 so -1 means keep existing level for that channel?
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
greengeek
Posts: 5789
Joined: Tue 20 Jul 2010, 09:34
Location: Republic of Novo Zelande

#285 Post by greengeek »

Ibidem wrote:But it does not have any tools for configuration, especially for setting up the first wpa_supplicant.conf. If someone wants to write one, I'd appreciate it...as long as they don't add too much bloat. .
Is that one of the configuration functions provided by rcrsn51's peasywifi? It seems a simple front end that worked well for me.

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#286 Post by Ibidem »

greengeek wrote:
Ibidem wrote:But it does not have any tools for configuration, especially for setting up the first wpa_supplicant.conf. If someone wants to write one, I'd appreciate it...as long as they don't add too much bloat. .
Is that one of the configuration functions provided by rcrsn51's peasywifi? It seems a simple front end that worked well for me.
Yes it is, but...to go with wpanet I'm looking for a tool that isn't going to try killing the wpa_supplicant process wpanet starts, starting wpa_supplicant itself without wpa_cli, using both gtkdialog3 and xdialog at the same time, while hard-coding the usage of a specific dhcp client that doesn't come with Busybox, and so on.
I'm sure it works for most purposes, but the backend is exactly what wpanet is about avoiding, the frontend is inextricably combined with the backend, and I figure that one *dialog is enough for what I want to do but I'd like to have a good range of systems the config tool can run on.
Support for gtk+1.2-only systems (gtkdialog1/xdialog) and plain textmode (select/dialog) is important.
[Edit]I wrote wpanet after I saw a dhcp client panic my kernel because it started at the wrong time while the wireless was not connected (kernel 2.6.32, Ubuntu 10.04, madwifi-hal-0.10.5.6). So I'm not using or recommending something that starts wpa_supplicant but doesn't use a wpa_cli action script to control the dhcp client.
[/Edit]

I was thinking of something that would use xdialog or dialog based on runtime detection of what's installed and working, that would _only_ deal with configuration, and that could coexist with any wpa_supplicant service that supports wpa_cli.
I have a skeleton of a prototype already; it uses dialog so making it use xdialog would be easy.

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

wpa_config, first public revision

#287 Post by Ibidem »

I've written a first pass at a wpa_config tool.
Note: this is intended for configuring wpa_supplicant, with a couple convenient extensions thrown in. It is not a network manager, though for the purpose of wireless networks it fills most of what I need.
I've tested it lightly using dialog; in theory, it should also work with Xdialog or whiptail.
To use another dialog, you would need to add a line setting DIALOG.
gdialog or zenity will not work, due to being barely compatible with ancient versions of dialog.
kdialog might or might not work; reports appreciated.
The "help" text at the top may not be very intelligeable to someone who isn't ready to configure wpa-supplicant with their text editor; if you can think of better wording or find it unclear, please comment.
Connecting to hidden networks is almost certainly broken and unsupported; I have none to test on.
If someone who has hidden networks in their area could run this:

Code: Select all

wpa_cli scan
wpa_cli scan_results >wpascanresults.txt
and provide the contents of wpascanresults.txt, that would be helpful.
If desired, I can make it only show wireless interfaces by default.

Code: Select all

#!/bin/sh
#
# wpa_config script by Isaac Dunham
# written and released into public domain under CC0 in 2014
#
# I expressly disclaim ANY WARANTEE IMPLIED OR STATED, INCLUDING,
# BUT NOT LIMITED TO, THE IMPLIED WARANTEES OF MERCHANTABILITY OR
# FITNESS FOR A PARTICULAR PURPOSE.
#
# wpa_config aims to be a dialog-based script for configuring wpa_supplicant
# with some aspects of a network manager thrown in.
# However, it stops short at starting/stopping/restarting wpa_supplicant
# itself; we leave that to system services.

mkdir -m 0700 -p /tmp/wpaconf || rm /tmp/wpaconf &&\
mkdir -m 0700 -p /tmp/wpaconf || {
	echo "Cannot obtain private tempdir!"
	exit 1
}

#DIALOG must implement:
# --insecure --output-fd --passwordbox --menu --inputbox --msgbox --fselect
# --insecure means "show asterisks"; I figure most people want that much acknowledgement.
# --fselect support is only needed for a couple features (user specified config files)

test -n "$DISPLAY" && DIALOG=`command -v Xdialog`
test -z "$DIALOG" && DIALOG=`command -v dialog`
# Unfortunately I have to live with whiptail...
test -z "$DIALOG" && DIALOG=`command -v whiptail`

newconf(){
echo "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=0" >$NEWCF
}

loadconfig(){
true >$CTRL
LOADCONFS="`[ -e /etc/wpa_supplicant/wpa_supplicant.conf ] && echo global /etc/wpa_supplicant/wpa_supplicant.conf`"
LOADCONFS="$LOADCONFS `[ -e /etc/wpa/$IFCUR.conf ] && echo local /etc/wpa/$IFCUR.conf`"
$DIALOG --output-fd 3 --menu "Which config file do you want to load?" 0 0 0 \
	$LOADCONFS other "browse for file" new "no file" 3>$CTRL
read conf <$CTRL
case $conf in
	new)	newconf
	;;
	global)	cat /etc/wpa_supplicant/wpa_supplicant.conf >$NEWCF
	;;
	local)	cat /etc/wpa/$IFCUR.conf >$NEWCF
	;;
	other)	true >$CTRL
		$DIALOG --output-fd 3 --fselect /etc 20 60 3>$CTRL
		read conf <$CTRL
		case "$conf" in
			*.conf)	true >$NEWCF
				grep ^ctrl_interface "$conf" >/dev/null || newconf
				cat "$conf" >>$NEWCF
			;;
			*)	$DIALOG --msgbox "No valid config file specified!" 0 0
			;;
		esac
	;;
esac
}

saveconfig(){
true >$CTRL
$DIALOG --output-fd 3 --menu \
"Choose a config file to write. WARNING! This WILL IMMEDIATELY OVERWRITE the file!" 0 0 0 \
	 global /etc/wpa_supplicant/wpa_supplicant.conf \
	 local /etc/wpa/$IFCUR.conf other "browse for file" 3>$CTRL
read conf <$CTRL
case $conf in
	global)	cat $NEWCF >/etc/wpa_supplicant/wpa_supplicant.conf
	;;
	local)	cat $NEWCF >/etc/wpa/$IFCUR.conf
	;;
	other)	true >$CTRL
		$DIALOG --output-fd 3 --fselect /etc 20 60 3>$CTRL
		read conf <$CTRL
		case "$conf" in
			*.conf)	cat $NEWCF >"$conf"
			;;
			*)	$DIALOG --msgbox "No valid config file specified!" 0 0
			;;
		esac
	;;
esac
}


setif(){
true >$CTRL
$DIALOG --output-fd 3 --menu "Select an interface:" 0 0 0 `ls /sys/class/net |sed -e 's/^\(.*\)$/\1 \1/g'` 3>$CTRL
read net <$CTRL
export IFCUR=${net:-$IFCUR}
unset net
}

net_add_open() {
true >$CTRL
test -z "$1" && $DIALOG --output-fd 3 --inputbox "Enter the SSID you wish to connect to.\nIf you enter 'any', the computer will\nconnect to any open network." 0 0 any 3>$CTRL
read net <$CTRL
test -n "$1" && net=$1
test -n "$net" || return
echo "network={" >> $NEWCF
case $net in
	any) ;;
	*) echo '	ssid="'"$net"'"' >>$NEWCF
	;;
esac
echo '	key_mgmt=NONE' >>$NEWCF
echo '}' >>$NEWCF
}

net_add_wep(){
true >$CTRL
$DIALOG --output-fd 3  --insecure --passwordbox "Enter the WEP key for SSID: $1"  0 0 3>$CTRL
test `wc -c <$CTRL` -gt 0 || return
cat >>$NEWCF <<EOF
network={
	ssid="$1"
	key_mgmt=IEEE8021X
	eap=MD5
	wep_key0=`cat $CTRL`
}
EOF
echo done >$CTRL
}

net_add_wpa() {
true >$CTRL
$DIALOG --output-fd 3  --insecure --passwordbox "Enter the passphrase for SSID: $1"  0 0 3>$CTRL
test `wc -c <$CTRL` -gt 0 || return
wpa_passphrase $1 <$CTRL >>$NEWCF
echo done >$CTRL
}

network_add() {
true >$CTRL
$DIALOG --output-fd 3 --inputbox "Enter the SSID you wish to connect to." 0 0 3>$CTRL
read net <$CTRL
test -n "$net" || return
true >$CTRL
$DIALOG --output-fd 3 --menu "Choose the network encryption:" 0 0 0 \
	No encryption WEP encryption WPA encryption 3>$CTRL || return
case `cat $CTRL` in
	No)	net_add_open $net
	;;
	WEP)	net_add_wep $net
	;;
	WPA)	net_add_wpa $net
	;;
esac
}

#scanner:
# scan
# save results to file
# parse from file
#Buttons:
#Refresh/Add/Leave
# Usage: IFCUR=if0 scanner
scanner() (
if test OK != "`wpa_cli -i "$IFCUR" scan `"
  then
    $DIALOG --msgbox "wpa_cll status for $IFCUR failed!" 0 0
    return
  fi
net=Rescan
while test -n "$net"
do
  case $net in
    Rescan)
      SCAN=`mktemp /tmp/wpaconf/scanXXXXXX`
      SCAN2=`mktemp /tmp/wpaconf/scanXXXXXX`
      wpa_cli -i "$IFCUR" scan_results >$SCAN

      echo '$DIALOG --output-fd 3 --menu "Select a network to connect to, or rescan." 0 0 0 \' >$SCAN2
      cat $SCAN |awk '{if (NF==5) print $1 "\t\""$5"\" \\";
                  else if (NF==4) print $1 "\t\"" $4"\" \\"; }' >>$SCAN2
      echo 'Rescan "for more networks" 3>$CTRL' >>$SCAN2
      true >$CTRL
      . $SCAN2
      read net <$CTRL
      ;;
    *:*:*:*)
      NET="`awk '{if ($1 == "'$net'") print $NF}' <$SCAN`"
      #network_add $NET
      case `awk '{if ($1 == "'$net'") if (NF == 5) print $4; else print "open"}' <$SCAN` in
      	*WPA*PSK*) net_add_wpa $NET
	;;
	*WEP*) net_add_wep $NET
	;;
	open) net_add_open $NET
      esac
      net=Rescan
      ;;
   esac
done
rm -f $SCAN $SCAN2
)

#initialize before main loop
CTRL=`mktemp /tmp/wpaconf/ctrlXXXXXX`
cmd=maindummy
NEWCF=`mktemp /tmp/wpaconf/confXXXXXX`
newconf
setif
test -n "$IFCUR" || exit 1

#Now, main loop:
while test -n "$cmd"
	do	true >$CTRL
		exec 3>$CTRL
		$DIALOG --output-fd 3 --menu "Select an operation:" 0 0 0 \
		  1 scan 2 disconnect 3 reassociate \
		  4 "change interface ($IFCUR)" 5 "add network" \
		  6 "load new config file" 7 "save config file" 8 "view config file"
		exec 3<&-
		read cmd <$CTRL
		case $cmd in
			1) scanner
			;;
			2) wpa_cli -i $IFCUR disconnect
			;;
			3) wpa_cli -i $IFCUR reassociate
			;;
			4) setif
			;;
			5) network_add
			;;
			6) loadconfig
			;;
			7) saveconfig
			;;
			8) $DIALOG --scrollbar --textbox $NEWCF 0 0
			;;
		esac
	done

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#288 Post by technosaurus »

It looks ok, except some bashisms:
command -v , can be removed if you don't have quoted args inside of args
if you need to run a program with a built list of args you can do this:
args="\"first arg\""
args="${args} \"second arg\""
#...
eval $MYCOMMAND "$args"

for open/wep wife, iw is the best tool I have come across (permissive license and well maintained)
http://wireless.kernel.org/en/users/Documentation/iw
built with libnl-tiny instead of the gpl'd netlink libs:
https://github.com/sabotage-linux/libnl-tiny

I have done a lot of further development on my MIME-type detector. All of the types are hard-coded but doing so gains a couple of orders of magnitude of speed over that _other_ tool (file + libmagic) by doing a binary search on inbuilt sorted values vs. a series of linear searches on xml-derived data. Feel free to mod it for your desktop environment or web server (its initial purpose was to quickly output the Content-type: ) It initially tries to guess the mime-type by file extension for speed (no file opening==no delay), then by magic@offset if not compiled with -DNO_MAGIC.
For a test program compile with:
gcc -DTEST -Os -fmerge-all-constants -fno-asynchronous-unwind-tables -fno-unwind-tables -o MIME3 MIME3.c -s
Available on Github
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#289 Post by Ibidem »

technosaurus wrote:It looks ok, except some bashisms:
command -v , can be removed if you don't have quoted args inside of args
if you need to run a program with a built list of args you can do this:

Code: Select all

args=""first arg""
args="${args} "second arg""
#...
eval $MYCOMMAND "$args"
command -v is POSIX not bash; it's the equivalent of which (which is a Linuxism).
The point there is:
Is there an executable for such-and-such dialog version?
It will return nothing if it's not found, the path if it is found.
for open/wep wife, iw is the best tool I have come across (permissive license and well maintained)
http://wireless.kernel.org/en/users/Documentation/iw
built with libnl-tiny instead of the gpl'd netlink libs:
https://github.com/sabotage-linux/libnl-tiny
First, libnl-tiny is originally an OpenWRT project, consisting simply of a partial fork of libnl 2.
As such, it is under the exact same license: LGPL 2.1.
libnl 3 is under LGPL 2.1 as well.
By the way, I'd like to say that libnl has a pretty responsive upstream; when I sent them a patch to make it work with musl (back in the early 0.9.x timeframe), I got a "thanks, applied" the next day.

Second, iw is not compatible with wext. This means it's out unless you have a recent kernel and in-kernel drivers.

Third, using iw is not going to simplify things.
wpa_config is intended to configure wpa_supplicant to connect to any network you want; wpa_supplicant is what I'm using because it's persistent, it supports all types of wireless networks, it's permissively licensed (BSD-style), and adding a persistent network doesn't take writing a script that you have to run at boot/manually, with a hacked-up parser to figure out whether you even can find the network you want, a case statement that really has to be modified manually if you want to handle roaming, and perhaps another hacked up parser to figure out if you've connected, plus the logic to start a dhcp client.

(That's what it takes to use iw/iwconfig properly, though if you only have one network you ever use and don't have any concerns about kernel panics you could set things up in two lines.)

When I was at the university, I had to have two wireless networks: one for home, one for school. The one at home was wpa, while school had an open network.
wpa_supplicant can connect to the right one automatically, with just this much configuration:

Code: Select all

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=network
network={
   ssid="school"
   key_mgmt=NONE
}
#autogenerated by wpa_passphrase wpa password
network={
	ssid="wpa"
	#psk="password"
	psk=3d2e41dbc74080cdb861baf815d70488312e6581b64f44bb2785db5c5a2f27bd
}
It's simpler to handle the errors and it works better (roaming, persistence, reassociation after dropped connections), so I want to make it even easier to use.
I have done a lot of further development on my MIME-type detector. All of the types are hard-coded but doing so gains a couple of orders of magnitude of speed over that _other_ tool (file + libmagic) by doing a binary search on inbuilt sorted values vs. a series of linear searches on xml-derived data. Feel free to mod it for your desktop environment or web server (its initial purpose was to quickly output the Content-type: ) It initially tries to guess the mime-type by file extension for speed (no file opening==no delay), then by magic@offset if not compiled with -DNO_MAGIC.
For a test program compile with:
gcc -DTEST -Os -fmerge-all-constants -fno-asynchronous-unwind-tables -fno-unwind-tables -o MIME3 MIME3.c -s
Available on Github
Neat.

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#290 Post by technosaurus »

Turns out the bashism checker i used had a bug report filed stating as such:
https://bugs.debian.org/cgi-bin/bugrepo ... bug=733511

I think Iguleder is using a ksh derivative (loksh) until toysh is complete

libnl-tiny seems to have lost the license file, I noticed the lgpl reference after the post in a random file, so unless it has a static linking exception that eliminates iw.
I had it in my mind that wpa_sup could't do wep, but just noticed /usr/share/doc/wpasupplicant/examples/wep.conf ... so disregard ... though openBSD's ifconfig seems workable too.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

Post Reply