Reading through the iw source code to figure out how to get the regulatory domain
is like reading through a ham radio radio manual to figure out how to turn it on.
Even when I could see what iw was doing there were no comments or directions as
to why they were doing it a specific way. And, I could not find any definitive
resources on nl80211 via netlink. Fortunately, Thomas Graf provides excellent
documentation on libnl at http://www.carisma.slowglass.com/~tgr/libnl/doc/core.html.
Reading this, I was able to write a simple netlink message class and parser. I still
cannot follow the iw code but with strace, I was able to copy the hex strings and
parse the communications to and from the kernel. However, this leaves a lot of
questions unaswered which is the purpose of this document - to document my
observations, findings and questions in a central location rather than dispersed
throughout the code.

1) Odd error on what should be a NLE_PERM
When running a root level cmd (reg set) as non-root), I get a return message w/
the following format:

    nlmsghdr(len=48, type=2, flags=5, seq=1460441619, pid=9865)
    genlmsghdr(cmd=255)
    attributes:
        0: type = 0, datatype = 0
        value = 1a00050013920c57892600001b000000070021005553

and the hex of this message is:

"\x30\x00\x00\x00\x02\x00\x00\x00\x13\x92\x0c\x57\x89\x26\x00\x00\xff\xff\xff\xff\x1c\x00\x00\x00\x1a\x00\x05\x00\x13\x92\x0c\x57\x89\x26\x00\x00\x1b\x00\x00\x00\x07\x00\x21\x00\x55\x53\x00\x00"

First, type=2 generally designates an error (at least when executing nl80211).
Second, there is no cmd = 255. Third attempting to parse it as an netlink error
results in a errno of -1. Finally, it does not follow the correct error message
format which should be nlmsghdr+errno+nlmsghdr.

I checked and this is the same response iw gets.

* workaround is in place in libnl.nlmsg_fromstream()

2) ACK messages
PyRIC is set up in a simple send a message & receive the response method. However,
if the caller designates the message with a NLM_F_ACK flag and the ack is not
pulled off the socket subsequent messages will fail due to sequence numbers
mismatching. This is only a problem when using a persistent netlink socket.
ATT I set the NLM_F_ACK flag on all sent packets to ensure we get ack messages
back.

* workaround is in place in libnl.nl_recvmsg

3) Hanging terminal
I don't attempt to parse attributes of type nested or unspec. In some situations
when printing the hex values of these attributes on the terminal some character
or set of characters causes the terminal to hang. No combinination of keys etc
can then kill the terminal. I haven't yet looked into trying to determine what
hex value(s) is causing this.

* workaround is in place in GENLMsg.__repr__ using hexlify

4) Using deprecated programs/processes
IOT to replicate iw dev <dev> info, one has to pass the ifindex (I've tried using
the device name with appropriate attribute type but it fails). The only way to
get the ifindex is by using the supposedly deprecated ioctl (iw does the same).
Seems kind of ironic that the 'new and improved' relies on the old and deprecated

* no workaround at this point

5) Error
Netlink provides error codes in netlink/errno.h. However these do not match those
found in /usr/include/asm-generic/errno-base.h and /usr/include/asm-generic/errno.h.
In most cases, it appears that using the netlink errors results in reporting an
incorrect error - there doesn't seem to be any rhyme or reason for this as even
the error codes reporting in the nlmsgerr struct fit linux errors over netlink
errors (in most cases). But, of course there is a catch. NLE_SUCCESS (0) and
NLE_FAILURE (1) as reported in ack/error messages are correct but do not correspond
to the same error code in the linux asm header files.

* workaround in place, added '-1' as an undefined, use errno for error codes,
error strings and test for NLE_SUCCESS in netlink error message

6) Setting the channel/Frequency
nl80211.h states that using NL80211_CMD_SET_WIPHY to set the channel is deprecated
in place of NL80211_CMD_SET_CHANNEL. Below is the attempted code:
phy = devinfoex(nlsock,nic)['phy']
msg = nl.nlmsg_new(nl_type=_FAM80211ID_,
                   cmd=nl80211h.NL80211_CMD_SET_CHANNEL,
                   flags=nlh.NLM_F_REQUEST | nlh.NLM_F_ACK)
msg.nla_put_u32(phy,nl80211h.NL80211_ATTR_WIPHY)
msg.nla_put_u32(channels.ch2rf(ch),nl80211h.NL80211_ATTR_WIPHY_FREQ)
msg.nla_put_u32(CHWIDTHS.index(chw),nl80211h.NL80211_ATTR_WIPHY_CHANNEL_TYPE)

and results in a 'invalid argument' error. So, am I sending the wrong crap? The
description for this command in nl80211_h

 * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ
 *	and the attributes determining channel width) the given interface
 *	(identifed by %NL80211_ATTR_IFINDEX) shall operate on.
 *	In case multiple channels are supported by the device, the mechanism
 *	with which it switches channels is implementation-defined.
 *	When a monitor interface is given, it can only switch channel while
 *	no other interfaces are operating to avoid disturbing the operation
 *	of any other interfaces, and other interfaces will again take
 *	precedence when they are used.

mentions ifindex. Adding the ifindex with:

msg.nla_put_u32(nl80211h.NL80211_ATTR_IFINDEX,8)

still gives an 'invalid argument' error. Took out channel width and still no go

* workaround in place, using the deprecated NL80211_CMD_SET_WIPHY

7) Would like to be able set the tx-power, not just to the max but lower or raise
as desired, neither of the below work in iw or through netlinks

dev <devname> set txpower <auto|fixed|limit> [<tx power in mBm>]
		Specify transmit power level and setting type.

phy <phyname> set txpower <auto|fixed|limit> [<tx power in mBm>]
		Specify transmit power level and setting type.

