HowTo (Mac) - Network

This is a first cut at a HowTo for setting up networking on Nerves.

Note: This page assumes that you have successfully completed the Install, Build, and Upload steps. It is based on notes provided by various folks on the Nerves Slack channel, including @jerel (Jerel Unruh), @paco (Francois Rebemont), and @tattdcodemonkey (Rodney Norris).

Hardware Support

Some Raspberry Pi models (e.g., 2B, 3B) have an Ethernet socket (10/100-BaseT). The 3B also has built-in Wi-Fi (2.4GHz 802.11n wireless), but the "interim" Wi-Fi support in Nerves is said to be a little finicky. So, for the moment, I'm concentrating on Ethernet-based access to my Local Area Network (LAN).

IP-based Networking

Internet Protocol (IP) networking can be used to support a variety of interaction modes, including file sharing, terminal sessions, etc. Nerves.Networking is a Nerves module that configures IP networking. It provides support for both dynamic and static IP addresses, as discussed below.

DHCP

Dynamic Host Configuration Protocol (DHCP) is very easy to set up on Nerves:

alias Nerves.Networking

interface      = :eth_s2
{:ok, _pid}    = Networking.setup(interface)

However (unless steps are taken to prevent this problem), the target won't have a fixed address. So, each time you boot the target, you may have to do something like:

$ arp -a | sort
? (192.168.1.1) at a0:ec:f9:82:bf:90 on en0 ifscope [ethernet]
...
? (192.168.1.255) at ff:ff:ff:ff:ff:ff on en0 ifscope [ethernet]

and then figure out which address belongs to the target. If you are on good terms with the network administrator, you may be able to get her to add the target to the local DHCP and/or Domain_Name_Service DNS configuration. If not, you may want to use static IP, instead.

Static IP

Setting up static IP addressing requires a number of configuration parameters, but it isn't all that hard:

alias Nerves.Networking

interface      = :eth_s2
static_config  = %{
  dns1:      "8.8.8.8",             # DNS server 1 (Google)
  dns2:      "8.8.4.4",             # DNS server 2 (Google)
  hostname:  "raspi_3b",            # hostname
  ip:        "192.168.0.5",         # target's IP address
  mask:      "8",                   # usable bits in subnet
  mode:      "static",              # use static IP
  router:    "192.168.0.1",         # router's IP address
  subnet:    "255.255.255.0"        # subnet mask }

{:ok, _pid}    = Networking.setup(:interface, static_config)

The mask and subnet fields seem a bit redundant to me, but I may well be missing something...

Elixir Networking

Elixir and, more generally, the Erlang Virtual Machine (VM), have their own notions about networking. Not surprisingly, these interact with IP addressing. If you're running multiple VM nodes on a single machine, you can identify them using a "short name". However, if the nodes are on multiple machines. you'll have to use a "long name". For example:

--sname foo     # short name (node foo on this machine)
--name foo@bar  # long name  (node foo on machine bar)

For example, you can set the name of the Nerves target in the vm.args file; it would look something like this:

# Name for the target node
-name nerves_01@192.168.0.5

# Cookie for distributed Erlang
-setcookie SECRET_THING

# Start the Elixir shell
-noshell
-user Elixir.IEx.CLI
-extra --no-halt

You now have two ways to talk to the target device over your LAN. First, you can connect to the node remotely and access an IEx session running on it:

$ iex --name local@192.168.0.6 --cookie SECRET_THING --remsh nerves_01@192.168.0.5
iex> IO.puts "I'm on the nerves device"

Alternatively, you can do the same thing without the --remsh. You can then connect the nodes together, send messages, start processes, and so forth (just in a distributed way):

$ iex --name local@192.168.0.6 --cookie SECRET_THING
iex> Node.ping :"nerves_01@192.168.0.5"
:pong
iex> Node.list
[:"nerves_01@192.168.0.5"]

At this point, you can interact with processes on the Nerves device like you would with any node in an Elixir cluster.

Notes: Most of the example above was written by Rodney Norris. Connecting Elixir nodes on the same LAN, by Benjamin Tan, is a nice introduction to this topic. See also Secure Shell for Your Erlang Node, by Marc Sugiyama.


This wiki page is maintained by Rich Morin, an independent consultant specializing in software design, development, and documentation. Please feel free to email comments, inquiries, suggestions, etc!

Topic revision: r8 - 19 Jul 2016, RichMorin
This site is powered by Foswiki Copyright © by the contributing authors. All material on this wiki is the property of the contributing authors.
Foswiki version v2.1.6, Release Foswiki-2.1.6, Plugin API version 2.4
Ideas, requests, problems regarding CFCL Wiki? Send us email