Skip to main content
Erschienen in:
Buchtitelbild

Open Access 2014 | OriginalPaper | Buchkapitel

5. Networking and Hacks

verfasst von : Manoel Carlos Ramon

Erschienen in: Intel® Galileo and Intel® Galileo Gen 2

Verlag: Apress

Aktivieren Sie unsere intelligente Suche, um passende Fachinhalte oder Patente zu finden.

search-config
insite
INHALT
download
DOWNLOAD
print
DRUCKEN
insite
SUCHEN
loading …

Abstract

Computers, mobile devices, surveillance systems, robots, cameras, smart TVs, thermostats, and many other devices can communicate each other using wired or wireless interfaces.
Computers, mobile devices, surveillance systems, robots, cameras, smart TVs, thermostats, and many other devices can communicate each other using wired or wireless interfaces.
The scope of such communication can be a simple intranet or external access using the Internet, making these devices accessible in any part of the world.
Intel Galileo boards are not only an Arduino board micro-controlled but are real microcomputers operated by Linux OS whose boards contain an Ethernet interface and a mini-PCIe slot that can receive mini-PCIe cards, including WiFi cards. This combination of software and hardware enables Intel Galileo to communicate with other devices in an intranet network or through the Internet using wired or wireless adapters, just like a regular computer.
This chapter provides information about how to:
  • Install WiFi cards and antennas
  • Add firmware for new WiFi mini-PCIe cards
  • Use the Arduino WiFi API
  • Hack the WiFi API and simplify the sketches
  • Create dynamic and static IPs via an Ethernet adapter
  • Use Internet access shared by your computer via Ethernet
  • Run samples of the Arduino Ethernet API
  • Simplify Ethernet sketches
  • Transfer files between Intel Galileo and other computers
  • Hack the IDE to transfer sketches via TCP/IP
Throughout the chapter, you’ll see several commands using the Linux terminal shell of Intel Galileo, so keep your serial cables in hand, as described in Chapter 1.

WiFi Cards

Intel Galileo and Intel Galileo Gen 2 contain a mini-PCIe slot at the bottom of the board that allows you to connect WiFi, Bluetooth, video cards, and other modules using the mini-PCIe form factor.
With the availability of this resource, the cost of integrating a WiFi card to the board is reduced because the WiFi mini-PCIe cards are usually cheaper than the regular WiFi shields design for Arduino. However, using a mini-PCIe card does not prevent you from using a regular Arduino API created specifically for WiFi shields. For example, if you are using the mini-PCIe slot for a video card but you need a WiFi, you need a WiFi shield.
The only requirement for using WiFi cards in terms of software is the SD image releases. This is because the SPI releases do not have enough space to hold the Linux WiFi drivers and the cards’ firmware.
With the Intel Galileo SD releases provided by Intel, the Intel N135 Centrino is supported by default, but in this chapter you learn how to add other cards using Intel 6236A.
Note
If your WiFi card is not manufactured by Intel and is not supported by an iwlwifi driver, this procedure will not work. In this case, it is necessary to search for your driver and integrate it into the Yocto builds, as explained in Chapter 2.

Setting Up the WiFi Mini-PCIe Card

In addition to the mini-PCIe card, you need the items listed in Table 5-1.
Table 5-1.
Materials List for WiFi Exercises
Number
Description
1
Intel WiFi mini-PCIe Intel Centrino model N135 or 6235A
2
Dual-band antennas 350mm cable 2118060-1 TE connectivity
1
Half to full height mini-PCIe card bracket
1
Micro SD card (minimum of 4GB)
The procedure for installing these cards on Galileo is quite simple, as explained in the following steps:
1.
Power off Intel Galileo. Remove the USB and power supply before starting.
 
2.
Install the half to full height bracket. Connect the brackets using the little screws, as shown in Figure 5-1.
 
3.
Connect the dual-band antennas in the card connector by pressing them down until you feel a small “click” in the connector. Check Figure 5-2 for reference.
 
4.
Insert the WiFi mini-PCIe card at an angle, making sure the card’s contacts are connected to the slot, as shown in Figure 5-3.
 
5.
Press the bracket down and connect the bracket’s holes to the slot’s plastic clips until you feel a click. Figure 5-4 shows the WiFi card properly connected.
 
6.
Download the BSP SD card image from the Intel Galileo web site at https://communities.intel.com/docs/DOC-22226 .
 
7.
Transfer the downloaded images to a micro SD card formatted as FAT32 or FAT and insert the SD card into Intel’s Galileo SD card slot.
 
8.
Connect the power supply and then the USB cable (exactly in this order, as explained in the section entitled Connecting Intel Galileo in Chapter 3.
 

Checking if the WiFi Card Was Recognized

If the card was inserted as expected using a Linux terminal shell, you can type ifconfig -a or ifconfig wlan0. You’ll see the following output:
root@clanton:∼# ifconfig -a
eth0      Link encap:Ethernet HWaddr 98:4F:EE:01:4C:71
          UP BROADCAST MULTICAST MTU:1500 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B) TX bytes:322 (322.0 B)
          Interrupt:40 Base address:0x8000
lo        Link encap:Local Loopback
          inet addr:127.0.0.1 Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING MTU:65536 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
wlan0     Link encap:Ethernet HWaddr 0C:D2:92:58:F8:27
          BROADCAST MULTICAST MTU:1500 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
You should be able to see the wlan0 interface. If this interface is not shown it means the SD image was not recognized by your card due to missing firmware or improper card installation. To resolve this problem, read the section entitled “Adding a New WiFi Card" in this chapter.
If the wlan0 interface is shown, at this point there is no IP associated with the interface. You need to scan the WiFi routers and use the right credentials and authentication methods to connect Intel Galileo.

Adding Support to a New WiFi Card

This section is useful only if you have a mini-PCIe WiFi card that hasn’t been recognized. Otherwise, you can move on to the next section.
If you have a mini-PCIe WiFi card that’s not recognized and you are sure you connected the card to the mini-PCIe slot correctly, it’s likely that the SD card image does not contain the firmware required for your card and you need to add it. The other possibility is that your card is damaged.
If your card is fine, you simply need to transfer the WiFi card’s firmware to the /lib/firmware folder and reboot the system.
For example, if your mini-PCIe WiFi card is Intel, use the following steps to upgrade your SD image to support the new card:
2.
On this web site, search for the Firmware section and download the firmware corresponding to your card. Figure 5-5 shows a list of the newest cards available from the web site.
 
3.
Transfer the file to Intel Galileo. You can transfer using scp or ftp, or simply copy the file to your SD card or connect a USB drive to Intel Galileo. Read the section entitled “Transferring Files Between Intel Galileo and Computers” in this chapter for the details. You can copy the downloaded file to a temporary file in your /root/home directory, for example.
 
4.
Extract the zipped tar file. For example:
 
root@clanton:∼/tmp# tar -zxvf iwlwifi-6000g2b-ucode-18.168.6.1.tgz
iwlwifi-6000g2b-ucode-18.168.6.1/
iwlwifi-6000g2b-ucode-18.168.6.1/iwlwifi-6000g2b-6.ucode
iwlwifi-6000g2b-ucode-18.168.6.1/README.iwlwifi-6000g2b-ucode
iwlwifi-6000g2b-ucode-18.168.6.1/LICENSE.iwlwifi-6000g2b-ucode
5.
The file that you really need has a .ucode extension. Move this file to the /lib/firmware folder.
 
mv iwlwifi-6000g2b-6.ucode /lib/firmware/.
6.
Reboot the system using the reboot command.
 
7.
After the reboot, log in again and check if the wlan0 interface is available using the ifconfig wlan0 command.
 
root@clanton:∼# ifconfig wlan0
wlan0     Link encap:Ethernet HWaddr C8:F7:33:A4:56:1E
          BROADCAST MULTICAST MTU:1500 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Your SD image should now support the new WiFi card without problems.

The WiFi API

If the card and the firmware were properly installed and recognized, it is possible to create some sketches using the WiFi adapter.
This section provides an introduction to this API by showing a couple of sketches in several examples present in the IDE. These examples also explain how these sketches can be optimized to run on Intel Galileo.
There are several examples related to the WiFi API in File ➤ Examples ➤ WiFi in the IDE. As an introduction, two sketches specifically are discussed—one that scans the wireless networks and the other that connects to one of the networks using WPA or WEP.
The full reference with details of the WiFi API for Arduino can be found at http://arduino.cc/en/Reference/WiFi .

Scanning the Wireless Networks

The first example scans the wireless networks and checks if your WiFi card is working.
Using the Intel Galileo IDE, open the example by choosing File ➤ Examples ➤ WiFi ➤ ScanNetworks.
Note that this code is not in the code folder of this chapter because this example is part of your IDE.
Listing 5-1 shows the code related to this scanning example.
Listing 5-1. ScanNetworks.ino
/*
This example prints the WiFi shield's MAC address and
scans for available WiFi networks using the WiFi shield.
Every ten seconds, it scans again. It doesn't actually
connect to any network, so no encryption scheme is specified.
Circuit:
* WiFi shield attached
created 13 July 2010
by dlf (Metodo2 srl)
modified 21 Junn 2012
by Tom Igoe and Jaymes Dec
*/
#include <SPI.h>
#include <WiFi.h>
void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while(true);
  }
  String fv = WiFi.firmwareVersion();
  if( fv != "1.1.0" )
    Serial.println("Please upgrade the firmware");
  // Print WiFi MAC address:
  printMacAddress();
  // scan for existing networks:
  Serial.println("Scanning available networks...");
  listNetworks();
}
void loop() {
  delay(10000);
  // scan for existing networks:
  Serial.println("Scanning available networks...");
  listNetworks();
}
void printMacAddress() {
  // the MAC address of your WiFi shield
  byte mac[6];
  // print your MAC address:
  WiFi.macAddress(mac);
  Serial.print("MAC: ");
  Serial.print(mac[5],HEX);
  Serial.print(":");
  Serial.print(mac[4],HEX);
  Serial.print(":");
  Serial.print(mac[3],HEX);
  Serial.print(":");
  Serial.print(mac[2],HEX);
  Serial.print(":");
  Serial.print(mac[1],HEX);
  Serial.print(":");
  Serial.println(mac[0],HEX);
}
void listNetworks() {
  // scan for nearby networks:
  Serial.println("** Scan Networks **");
  int numSsid = WiFi.scanNetworks();
  if (numSsid == -1)
  {
    Serial.println("Couldn't get a wifi connection");
    while(true);
  }
  // print the list of networks seen:
  Serial.print("number of available networks:");
  Serial.println(numSsid);
  // print the network number and name for each network found:
  for (int thisNet = 0; thisNet<numSsid; thisNet++) {
    Serial.print(thisNet);
    Serial.print(") ");
    Serial.print(WiFi.SSID(thisNet));
    Serial.print("\tSignal: ");
    Serial.print(WiFi.RSSI(thisNet));
    Serial.print(" dBm");
    Serial.print("\tEncryption: ");
    printEncryptionType(WiFi.encryptionType(thisNet));
  }
}
void printEncryptionType(int thisType) {
  // read the encryption type and print out the name:
  switch (thisType) {
  case ENC_TYPE_WEP:
    Serial.println("WEP");
    break;
  case ENC_TYPE_TKIP:
    Serial.println("WPA");
    break;
  case ENC_TYPE_CCMP:
    Serial.println("WPA2");
    break;
  case ENC_TYPE_NONE:
    Serial.println("None");
    break;
  case ENC_TYPE_AUTO:
    Serial.println("Auto");
    break;
  }
}
Run the sketch and then open the IDE serial console by choosing Tools ➤ Serial Monitor or pressing CTRL+SHIFT+M.
In few seconds, you will be able to see your WiFi MAC address as the output, along with the wireless networks scanned around Intel Galileo with their respective power level and encryption method. For example:
MAC: 1E:56:A4:33:F7:C8
Scanning available networks...
** Scan Networks **
number of available networks:3
0) 55JW5        Signal: -89 dBm Encryption: None
1) PXDP6        Signal: -79 dBm Encryption: WPA2
2) WDJ36        Signal: -84 dBm Encryption: None

Reviewing ScanNetworks.ino

The inclusion of the WiFi.h header gives you access to WiFi classes and functions. There are some static methods excluded from the sketch regarding object instantiations.
#include <WiFi.h>
Using the WiFi object, the program checks if the WiFi card is in place:
if (WiFi.status() == WL_NO_SHIELD)
If the card is not installed, WL_NO_SHIELD is returned and the program is aborted. Then next section of the code checks the firmware version:
String fv = WiFi.firmwareVersion();
  if( fv != "1.1.0" )
    Serial.println("Please upgrade the firmware");
This line checks the firmware version and prints a warning message if the firmware does not match the latest version.
The sketches prints the MAC address by calling WiFi.macAddress() and passing a byte array as the reference. This call is done by the local function printMacAddress() .
void printMacAddress() {
  // the MAC address of your WiFi shield
  byte mac[6];
  // print your MAC address:
  WiFi.macAddress(mac);
  Serial.print("MAC: ");
  Serial.print(mac[5],HEX);
  Serial.print(":");
  Serial.print(mac[4],HEX);
  Serial.print(":");
  Serial.print(mac[3],HEX);
  Serial.print(":");
  Serial.print(mac[2],HEX);
  Serial.print(":");
  Serial.print(mac[1],HEX);
  Serial.print(":");
  Serial.println(mac[0],HEX);
}
The setup() function ends the call to the local function listNetworks(), which is where the magic happens.
The listNetworks() function calls the method WiFi.scanNetworks(), which returns the total number of WiFi networks found during scanning. At this moment, an internal array is created, starting from 0 to the number of wireless networks found minus one. Each element of this array contains information related to each network scanned.
void listNetworks() {
  // scan for nearby networks:
  Serial.println("** Scan Networks **");
  int numSsid = WiFi.scanNetworks();
  if (numSsid == -1)
  {
    Serial.println("Couldn't get a wifi connection");
    while(true);
  }
...
...
...
}
To retrieve information about each network scanned, the methods WiFi.SSID(), WiFi.RSSI(), and WiFi.encryptionType() are called and passed to the network index as references.
The sketch implements a for loop that prints the information about each network using the methods mentioned with the appropriate index.
void listNetworks() {
...
...
...
  // print the network number and name for each network found:
  for (int thisNet = 0; thisNet<numSsid; thisNet++) {
    Serial.print(thisNet);
    Serial.print(") ");
    Serial.print(WiFi.SSID(thisNet));
    Serial.print("\tSignal: ");
    Serial.print(WiFi.RSSI(thisNet));
    Serial.print(" dBm");
    Serial.print("\tEncryption: ");
    printEncryptionType(WiFi.encryptionType(thisNet));
  }
}
Note that the method WiFi.encryptionType() returns integers that specify the encryption used and are parsed properly by the local function printEncryptionType().
void printEncryptionType(int thisType) {
  // read the encryption type and print out the name:
  switch (thisType) {
  case ENC_TYPE_WEP:
    Serial.println("WEP");
    break;
  case ENC_TYPE_TKIP:
    Serial.println("WPA");
    break;
  case ENC_TYPE_CCMP:
    Serial.println("WPA2");
    break;
  case ENC_TYPE_NONE:
    Serial.println("None");
    break;
  case ENC_TYPE_AUTO:
    Serial.println("Auto");
    break;
  }
}
If you can list the WiFi networks that are available. The next step is to connect to some of these networks, as explained in the next sections.

Connecting to the WPA or WEB

Choose a WiFi network you have access to and determine whether the network requires WPA (WiFi Protected Access) or WEP (Wired Equivalent Privacy). Using the Intel Galileo IDE, open one of the following examples:
1.
If the WiFi network requests WPA, open the example File ➤ Examples ➤ WiFi ➤ ConnectWithWPA. See Listing 5-2.
 
2.
If the WiFi network requests WEP, open the example File ➤ Examples ➤ WiFi ➤ ConnectWithWEP. See Listing 5-3.
 
Listing 5-2. ConnectWithWPA.ino
/*
This example connects to an unencrypted WiFi network.
Then it prints the MAC address of the WiFi shield,
the IP address obtained, and other network details.
Circuit:
* WiFi shield attached
created 13 July 2010
by dlf (Metodo2 srl)
modified 31 May 2012
by Tom Igoe
*/
#include <WiFi.h>
char ssid[] = "yournetwork";     //  your network SSID (name)
char pass[] = "secretPassword";  // your network password
int status = WL_IDLE_STATUS;     // the WiFi radio's status
void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while(true);
  }
  String fv = WiFi.firmwareVersion();
  if( fv != "1.1.0" )
    Serial.println("Please upgrade the firmware");
// attempt to connect to WiFi network:
while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);
    // wait 10 seconds for connection:
    delay(10000);
  }
  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();
}
void loop() {
  // check the network connection once every 10 seconds:
  delay(10000);
  printCurrentNet();
}
void printWifiData() {
  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
    Serial.print("IP Address: ");
  Serial.println(ip);
  Serial.println(ip);
  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  Serial.print(mac[5],HEX);
  Serial.print(":");
  Serial.print(mac[4],HEX);
  Serial.print(":");
  Serial.print(mac[3],HEX);
  Serial.print(":");
  Serial.print(mac[2],HEX);
  Serial.print(":");
  Serial.print(mac[1],HEX);
  Serial.print(":");
  Serial.println(mac[0],HEX);
}
void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  Serial.print(bssid[5],HEX);
  Serial.print(":");
  Serial.print(bssid[4],HEX);
  Serial.print(":");
  Serial.print(bssid[3],HEX);
  Serial.print(":");
  Serial.print(bssid[2],HEX);
  Serial.print(":");
  Serial.print(bssid[1],HEX);
  Serial.print(":");
  Serial.println(bssid[0],HEX);
  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);
  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption,HEX);
  Serial.println();
}
Listing 5-3. ConnectWithWEP.ino
/*
This example connects to a WEP-encrypted WiFi network.
Then it prints the MAC address of the WiFi shield,
the IP address obtained, and other network details.
If you use 40-bit WEP, you need a key that is 10 characters long,
and the characters must be hexadecimal (0-9 or A-F).
e.g.  for 40-bit, ABBADEAF01 will work, but ABBADEAF won't work
(too short) and ABBAISDEAF won't work (I and S are not
hexadecimal characters).
For 128-bit, you need a string that is 26 characters long.
D0D0DEADF00DABBADEAFBEADED will work because it's 26 characters,
all in the 0-9, A-F range.
Circuit:
* WiFi shield attached
created 13 July 2010
by dlf (Metodo2 srl)
modified 31 May 2012
by Tom Igoe
*/
#include <WiFi.h>
char ssid[] = "yourNetwork";               // your network SSID (name)
char key[] = "D0D0DEADF00DABBADEAFBEADED"; // your network key
int keyIndex = 0;                          // your network key Index number
int status = WL_IDLE_STATUS;               // the WiFi radio's status
void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while(true);
  }
  String fv = WiFi.firmwareVersion();
  if( fv != "1.1.0" )
    Serial.println("Please upgrade the firmware");
  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WEP network, SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, keyIndex, key);
    // wait 10 seconds for connection:
    delay(10000);
  }
  // once you are connected :
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();
}
void loop() {
  // check the network connection once every 10 seconds:
  delay(10000);
  printCurrentNet();
}
void printWifiData() {
  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  Serial.println(ip);
  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  Serial.print(mac[5],HEX);
  Serial.print(":");
  Serial.print(mac[4],HEX);
  Serial.print(":");
  Serial.print(mac[3],HEX);
  Serial.print(":");
  Serial.print(mac[2],HEX);
  Serial.print(":");
  Serial.print(mac[1],HEX);
  Serial.print(":");
  Serial.println(mac[0],HEX);
}
void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  Serial.print(bssid[5],HEX);
  Serial.print(":");
  Serial.print(bssid[4],HEX);
  Serial.print(":");
  Serial.print(bssid[3],HEX);
  Serial.print(":");
  Serial.print(bssid[2],HEX);
  Serial.print(":");
  Serial.print(bssid[1],HEX);
  Serial.print(":");
  Serial.println(bssid[0],HEX);
  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);
  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption,HEX);
  Serial.println();
}
Both examples have the same goal, which is to provide access to your WiFi network. There are minor changes between two programs that will be reviewed later. In order to make the examples work, it is necessary to provide your credentials. If you are using the WPA example, the only lines that must be changed are in the beginning of sketch:
#include <WiFi.h>
char ssid[] = " yourNetwork ";     // your network SSID (name)
char pass[] = " secretPassword ";  // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status
If you are using WEP examples, you need to provide the username and the network’s key and key index. The key should be 10 characters long if WEP uses 40 bits or 26 bits long if WEP uses 128 bits.
#include <WiFi.h>
char ssid[] = " yourNetwork ";                // your network SSID (name)
char key[] = "D0D0DEADF00DABBADEAFBEADED";  // your network key
int keyIndex = 0;                           // your network key Index number
Edit these lines with your credentials and run the sketch. As soon as it runs, open the IDE serial console by using Tools ➤ Serial Monitor or pressing CTRL+SHIFT+M.
After a few seconds, you will see similar messages in your IDE serial console:
Attempting to connect to WPA SSID: S6KFF
You're connected to the networkSSID: S6KFF
BSSID: C6:0:7B:28:7F:0
signal strength (RSSI):-58
Encryption Type:4
IP Address: 192.168.  1.  7
192.168.  1.  7
MAC address: 27:F8:58:92:D2:C
SSID: S6KFF
BSSID: C6:0:7B:28:7F:0
signal strength (RSSI):-58
Encryption Type:4
This example used WPA. The network name is S6KFF (my personal one) and the IP was acquired as expected (192.168.1.7). The MAC address of the WiFi card in the example is 0x27f85892d20c.
If you have a USB cable attached and a terminal shell opened, in parallel to the Linux terminal shell, you will see messages like these:
[  736.741664] wlan0: deauthenticating from 00:7f:28:7b:00:c6 by local choice (reason=3)
[  736.762909] cfg80211: Calling CRDA to update world regulatory domain
[  741.827223] iwlwifi 0000:01:00.0: L1 Disabled; Enabling L0S
[  741.841249] iwlwifi 0000:01:00.0: Radio type=0x0-0x0-0x0
[  742.111928] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
[  742.598315] wlan0: authenticate with 00:7f:28:7b:00:c6
[  742.643220] wlan0: send auth to 00:7f:28:7b:00:c6 (try 1/3)
[  742.650993] wlan0: authenticated
[  742.660676] wlan0: associate with 00:7f:28:7b:00:c6 (try 1/3)
[  742.670682] wlan0: RX AssocResp from 00:7f:28:7b:00:c6 (capab=0x431 status=0 aid=1)
[  742.682587] wlan0: associated
[  742.685652] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
These messages appear while the IP is being acquired with WPA. Note the message "wlan0: link becomes ready", which indicates that the wlan0 is ready to be used.
If the WiFi router is connected to the Internet, try to ping Intel using the terminal shell:
root@clanton:∼# ping www.intel.com
PING www.intel.com (63.80.4.74): 56 data bytes
64 bytes from 63.80.4.74: seq=0 ttl=60 time=26.506 ms
64 bytes from 63.80.4.74: seq=1 ttl=60 time=26.525 ms
64 bytes from 63.80.4.74: seq=2 ttl=60 time=28.880 ms
64 bytes from 63.80.4.74: seq=3 ttl=60 time=27.931 ms

Reviewing ConnectWithWPA.ino and ConnectWithWEP.ino

The code used in the example is very simple and there are minor changes between the WPA and WEP examples. The whole connection process starts with the setup() function.
Initially, it is necessary to provide the credentials as explained in the previous section. The program then determines if the card is in place:
if (WiFi.status() == WL_NO_SHIELD)
If the card is not installed, WL_NO_SHIELD is returned and the program is aborted. Then next section of the code checks the firmware version:
String fv = WiFi.firmwareVersion();
  if( fv != "1.1.0" )
    Serial.println("Please upgrade the firmware");
This line checks the firmware version and prints a warning message if the firmware does not match the latest version. Don’t worry about this method because BSP always returns 1.1.0. This method is useless with Intel Galileo.
The connection is established using the WiFi.begin() call. If you are using the WPA example, the following code snippet describes the process for connecting:
// attempt to connect to Wifi network:
while ( status != WL_CONNECTED) {
  Serial.print("Attempting to connect to WPA SSID: ");
  Serial.println(ssid);
  // Connect to WPA/WPA2 network:
  status = WiFi.begin(ssid, pass);
  // wait 10 seconds for connection:
  delay(10000);
}
If you are using WEP, this code snippet establishes the connection:
while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WEP network, SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, keyIndex, key);
    // wait 10 seconds for connection:
    delay(10000);
}
In both examples, the program will try to connect through the WiFi.begin() functional call every 10 seconds, which is calculated by delay() function, and will keep trying in the while loop until the status returned by WiFi.begin() is WL_CONNECTED.
The only difference is in the begin() method. For WPA, the user credentials are passed in WiFi.begin(ssid, pass), whereas with WEP, the keys are used with WiFi.begin(ssid, keyIndex, key).
The rest of program is identical for both WPA and WEP. The loop() function calls printCurrentNet(), which prints some info regarding the connection. For example, WiFi.BSSID() connects the MAC address of the router, WiFi.RSSI() reports the signal strengths, and WiFi.encryptionType() reports the type of encryption.

Hacking the WiFi Library

This hack is applicable to Intel Galileo and Intel Galileo Gen 2.
If you played with the sketches mentioned in the section “Testing the WiFi Mini-PCIe” in this chapter or if you played with any other sketches running other WiFi examples from the IDE, you should have noticed that every time you run the sketches the connection to the WiFi routers is redone. This takes time. If you are developing a project that requires WiFi, this will be considered a huge annoyance for sure.
However, considering that the Intel Galileo boards use Linux as the operating system, it is possible to set the WiFi connection in the board to be persisted. With a few changes in the sketches, the development process will become very fast.
In other words, Intel Galileo will try to establish the connection as soon as the board boots or as soon as the network interfaces restart, without any sketch or native code for it.
With the WiFi connection handled by the Linux kernel, the sketches will not need to find the SSID. Instead, the sketches will use the connection that’s present, which will drastically improve the sketch development cycle.
To do this, follow these steps:
1.
Set up your connection using the terminal shell on Linux OS.
 
2.
Restart the wireless interface.
 
3.
Perform a small hack in the WiFi library class.
 

Step 1: Setting Up the WiFi Connection

In the context of Linux for Intel Galileo, the WiFi card is enumerated with the interface called wlan0. This interface will be mentioned several times in the terminal shell command lines.
The following sections explain how to create such a setup for the WPA and WEP connections.

Persisted Connection with WPA

You can use the command-line tool wpa_passphrase to generate the PSK (Pre-Shared Key) for the WPA connection. You pass the network name (SSID) and password for connecting to this command. It’s then possible to create a configuration file as shown here:
root@clanton:∼# wpa_passphrase YOUR_SSID YOUR_PASSWORD_HERE > /etc/wpa_supplicant.conf
You can then set Intel Galileo to connect to the WiFi router automatically by editing the /etc/network/interfaces file. You can edit this file directly in the command shell using the vi editor.
root@clanton:∼# vi /etc/network/interfaces
The auto wlan0 directive is added to the beginning of iface wlan0, as shown here:
# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)
# The loopback interface
auto lo
iface lo inet loopback
# Wireless interfaces
auto wlan0
iface wlan0 inet dhcp
        wireless_mode managed
        wireless_essid any
        wpa-driver wext
        wpa-conf /etc/wpa_supplicant.conf
iface atml0 inet dhcp
# Wired or wireless interfaces
auto eth0
iface eth0 inet dhcp
iface eth1 inet dhcp
# Ethernet/RNDIS gadget (g_ether)
# ... or on host side, usbnet and random hwaddr
iface usb0 inet static
        address 192.168.7.2
        netmask 255.255.255.0
        network 192.168.7.0
        gateway 192.168.7.1
# Bluetooth networking
iface bnep0 inet dhcp
Note that the WPA searches for the file /etc/wpa_supplicant.conf , which you created with wpa_passphrase, observing the wpa-conf /etc/wpa_supplicant.conf field.

Persisted Connection with WEP

The WEP procedure is similar to the WPA one.
Edit the /etc/network/interfaces file and add the line auto wlan0 to the top of iface wlan0, following the same procedure used in the WPA configuration discussed in the previous section.
It’s necessary to include the SSID and the key to be used as well. See the following example:
# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)
# The loopback interface
auto lo
iface lo inet loopback
# Wireless interfaces
auto wlan0
iface wlan0 inet dhcp
        wireless_mode managed
        wireless-essid your_network_ssid        wireless-key 0123456789ABCDEF0123456789
        wpa-driver wext
iface atml0 inet dhcp
# Wired or wireless interfaces
auto eth0
iface eth0 inet dhcp
iface eth1 inet dhcp
# Ethernet/RNDIS gadget (g_ether)
# ... or on host side, usbnet and random hwaddr
iface usb0 inet static
        address 192.168.7.2
        netmask 255.255.255.0
        network 192.168.7.0
        gateway 192.168.7.1
# Bluetooth networking
iface bnep0 inet dhcp

Step 2: Restart the Wireless Connection

Restart the connection by typing the following command:
root@clanton:∼# /etc/init.d/networking restart
If the WiFi router was identified and the connection is accepted, something similar to the following output will appear:
Running /etc/init.d/networking restart is deprecated because it may not enable again some interfaces
Reconfiguring network interfaces...
[ 5786.598692] wlan0: deauthenticating from 00:7f:28:7b:00:c6 by local choice (reason=3)
[ 5786.630939] cfg80211: Calling CRDA to update world regulatory domain
ifdown: interface eth0 not configured
Successfully initialized wpa_sup[ 5786.932111] iwlwifi 0000:01:00.0: L1 Disabled; Enabling L0S
plicant
[ 5786.946981] iwlwifi 0000:01:00.0: Radio type=0x0-0x0-0x0
[ 5787.228184] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
udhcpc (v1.20.2) started
Sending discover...
[ 5787.881882] wlan0: authenticate with 00:7f:28:7b:00:c6
[ 5787.925896] wlan0: send auth to 00:7f:28:7b:00:c6 (try 1/3)
[ 5787.933589] wlan0: authenticated
[ 5787.940668] wlan0: associate with 00:7f:28:7b:00:c6 (try 1/3)
[ 5787.950731] wlan0: RX AssocResp from 00:7f:28:7b:00:c6 (capab=0x431 status=0 aid=3)
[ 5787.962655] wlan0: associated
[ 5787.965719] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
Sending discover...
Sending select for 192.168.1.10...
Lease of 192.168.1.10 obtained, lease time 86400
/etc/udhcpc.d/50default: Adding DNS 192.168.1.1
udhcpc (v1.20.2) started
Sending discover...
Sending discover...
Sending discover...
No lease, failing
In this case, wlan0 is available and the connection to WiFi router is completed, so the IP is received and the DNS is set with success. If you reboot the board, the WiFi connection will automatically be re-established.
It is possible also to disable and enable the interface using the ifdown and ifup commands, respectively. Just type the command followed by the "wlan0" string to specify the wireless interface. See the following examples:
root@clanton:/etc/network# ifdown wlan0
[  717.113913] wlan0: deauthenticating from 00:7f:28:7b:00:c6 by local choice (reason=3)
[  717.150903] cfg80211: Calling CRDA for country: US
root@clanton:/etc/network# ifup wlan0
Successfully initialized wpa_sup[  722.047319] iwlwifi 0000:01:00.0: L1 Disabled; Enabling L0S
plicant
[  722.062243] iwlwifi 0000:01:00.0: Radio type=0x0-0x0-0x0
[  722.347953] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
udhcpc (v1.20.2) started
Sending discover...
[  723.026324] wlan0: authenticate with 00:7f:28:7b:00:c6
[  723.080172] wlan0: send auth to 00:7f:28:7b:00:c6 (try 1/3)
[  723.087765] wlan0: authenticated
[  723.100140] wlan0: associate with 00:7f:28:7b:00:c6 (try 1/3)
[  723.110014] wlan0: RX AssocResp from 00:7f:28:7b:00:c6 (capab=0x431 status=0 aid=3)
[  723.122344] wlan0: associated
[  723.125408] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
Sending discover...
Sending select for 192.168.1.7...
Lease of 192.168.1.7 obtained, lease time 86400
/etc/udhcpc.d/50default: Adding DNS 192.168.1.1

Step 3: Hacking the WiFi Class

At this point the Intel Galileo WPA or WEP connection process is persisted and functional, so you need to make a small change in the WiFi class to allow sketch to use this Linux connection instead of having to pass through the whole process again very quickly.
To understand how this is possible, take a look at the begin() methods implemented in the WiFi library class. Open the ./hardware/arduino/x86/libraries/WiFi/WiFi.cpp file and search for the two begin() methods:
int WiFiClass::begin(char* ssid, uint8_t key_idx, const char *key)
{
        char cmd[256];
        trace_debug("begin ssid=%s,key_idx=%d,key=%s",ssid,key_idx,key);
        /*
        iwconfig [interface] mode managed key [WEP key]
        (128 bit WEP use 26 hex characters, 64 bit WEP uses 10)
        */
        if(ssid == NULL)
                return WL_NO_SSID_AVAIL;
        if(key == NULL)
                return WL_CONNECT_FAILED;
        sprintf(cmd, "iwconfig wlan0 mode managed key %s", key);
        system(cmd);
        sprintf(cmd, "iwconfig wlan0 essid %s", ssid);
        system(cmd);
        sprintf(cmd, "ifup %s", ARDUINO_WLAN);
        system(cmd);
        delay(5000);
        _local_ip = getLocalIP();
        if(_local_ip._sin.sin_addr.s_addr == 0) {
                trace_debug("didnt get an IP address, cant connect");
                sprintf(cmd, "ifdown %s", ARDUINO_WLAN);
                _status = WL_IDLE_STATUS;
                return _status;
        }
        _subnet = getSubnet();
        strcpy(_ssid, ssid);
        _status = WL_CONNECTED;
        return _status;
}
int WiFiClass::begin(char* ssid, const char *passphrase)
{
        char cmd[256];
        trace_debug("begin ssid=%s,passphrase=%s",ssid,passphrase);
        if(ssid == NULL)
                return WL_NO_SSID_AVAIL;
        if(passphrase == NULL)
                return WL_CONNECT_FAILED;
        sprintf(cmd, "iwconfig wlan0 mode managed");
        system(cmd);
        sprintf(cmd, "iwconfig wlan0 essid %s", ssid);
        system(cmd);
        sprintf(cmd, "wpa_passphrase %s %s  > /etc/wpa_supplicant.conf",
                        ssid, passphrase);
        system(cmd);
        sprintf(cmd, "ifup %s", ARDUINO_WLAN);
        system(cmd);
        delay(5000);
        _local_ip = getLocalIP();
        if(_local_ip._sin.sin_addr.s_addr == 0) {
                trace_debug("didnt get an IP address, cant connect");
                sprintf(cmd, "ifdown %s", ARDUINO_WLAN);
                _status = WL_IDLE_STATUS;
                return _status;
        }
        _subnet = getSubnet();
        strcpy(_ssid, ssid);
        _status = WL_CONNECTED;
        return _status;
}
The first begin() method is used with a WEP connection and the second is with a WPA connection. If you take a look at the bold code in both methods, the sketches try to do the same procedure you have done manually, but instead of using the configuration for wlan0 present in the /etc/network/interfaces. file, the sketches use the iwconfig, wpa_passphrase, and ifup commands. In other words, the system calls send the commands to Linux in same way they would be typed into the terminal shell.
The iwconfig command tool sets up the wireless interface. In the begin() method that’s used for WPA and WEP, the iwconfig wlan0 mode managed and iwconfig wlan0 mode managed key %s commands are used, respectively. These commands set the wlan0 interface to be managed by the access point called mode managed. In other words, the access point will determine the channel frequency that Intel Galileo might camp. Note that, in WEP, the key is included at the end of the command line and %s will receive the char pointer key passed to the begin() method. This makes the key part of the command. This key might be represented by a 10-hexadecimal string if WEP used encryption with 40 bits or a 26-hexadecimal string if the WEP encryption is 128 bits.
The next usage of iwconfig and is to set the SSID name with iwconfig wlan0 essid %s, where %s receives the char pointer SSID with the network SSID name.
In the WPA, there is also a wpa_passphrase command being used in the same way it was used in the “Persisted Connection with WPA” section of this chapter. In this case, it simply generates a configuration file for the WPA connection.
Both methods call ifup wlan0 (since ARDUINO_WLAN is the string "wlan0") to make the wlan0 interface available. To make everything worse, there is a five-second delay implemented by the delay() function on this process.
Finally, the original code in both methods checks if the IP is available through getLocalIP(). If it is, the status WL_CONNECTED is returned; otherwise, WL_IDLE_STATUS is used.
When the WiFi connection is manually configured and persisted in Intel Galileo, the system simply has to determine if there is an IP available for the wlan0 interface once Linux can handle the connection.
Thus, if you are developing a project that uses WiFi and you want to speed up the sketch execution by avoiding this process, make the following simple changes to the code:
int WiFiClass ::begin(char* ssid, uint8_t key_idx, const char *key)
{
        char cmd[256];
        local_ip = getLocalIP();
        if(_local_ip._sin.sin_addr.s_addr == 0) {
            trace_debug("begin ssid=%s,key_idx=%d,key=%s",ssid,key_idx,key);
            /*
            iwconfig [interface] mode managed key [WEP key]
            (128 bit WEP use 26 hex characters, 64 bit WEP uses 10)
            */
            if(ssid == NULL)
                return WL_NO_SSID_AVAIL;
            if(key == NULL)
                return WL_CONNECT_FAILED;
            sprintf(cmd, "iwconfig wlan0 mode managed key %s", key);
            system(cmd);
            sprintf(cmd, "iwconfig wlan0 essid %s", ssid);
            system(cmd);
            sprintf(cmd, "ifup %s", ARDUINO_WLAN);
            system(cmd);
            delay(5000);
            _local_ip = getLocalIP();
            if(_local_ip._sin.sin_addr.s_addr == 0) {
                trace_debug("didnt get an IP address, cant connect");
                    sprintf(cmd, "ifdown %s", ARDUINO_WLAN);
                    _status = WL_IDLE_STATUS;
                    return _status;
            }
        }
        _subnet = getSubnet();
        strcpy(_ssid, ssid);
        _status = WL_CONNECTED;
        return _status;
}
int WiFiClass ::begin(char* ssid, const char *passphrase)
{
        char cmd[256];
        local_ip = getLocalIP();
        if(_local_ip._sin.sin_addr.s_addr == 0) {
             trace_debug("begin ssid=%s,passphrase=%s",ssid,passphrase);
             if(ssid == NULL)
                     return WL_NO_SSID_AVAIL;
             if(passphrase == NULL)
                     return WL_CONNECT_FAILED;
             sprintf(cmd, "iwconfig wlan0 mode managed");
             system(cmd);
             sprintf(cmd, "iwconfig wlan0 essid %s", ssid);
             system(cmd);
             sprintf(cmd, "wpa_passphrase %s %s  > /etc/wpa_supplicant.conf",
                        ssid, passphrase);
             system(cmd);
             sprintf(cmd, "ifup %s", ARDUINO_WLAN);
             system(cmd);
             delay(5000);
             _local_ip = getLocalIP();
             if(_local_ip._sin.sin_addr.s_addr == 0) {
                     trace_debug("didnt get an IP address, cant connect");
                     sprintf(cmd, "ifdown %s", ARDUINO_WLAN);
                     _status = WL_IDLE_STATUS;
                     return _status;
             }
        }
        _subnet = getSubnet();
        strcpy(_ssid, ssid);
        _status = WL_CONNECTED;
        return _status;
}
First off, the code determines whether there is a valid IP for the interface wlan0 through the function getLocalIP(). If there is, the authentication process is avoided. That means there is no needed to specify the SSID, a password, or the keys in the sketches once these fields are already configured (as demonstrated in the first step).
You can run the sketches from Listings 5-1 and 5-2 again without changing the SSID, key, or passwords. The programs will run very fast and work perfectly.

Ethernet API

One advantage to having Intel Galileo boards is the presence of Ethernet connector, which eliminates the need of an external shield. The Quark SoC supports two Ethernet interfaces but only one is available on the Intel Galileo boards.
In terms of Ethernet API, Intel Galileo complies with the Arduino reference. There are several classes implemented on this API: Ethernet, EthernetClient, EthernetUDP, IPAddress, and Server. For details, visit http://arduino.cc/en/reference/ethernet .
When this API was created, the purpose was to support Ethernet shields and Ethernet is the primary class used to configure the Ethernet adapter.
For example, to configure the Ethernet interface using the DHCP connection, you must determine the board MAC address and call the proper begin() method of this class. The following code snippet shows this process:
#include <Ethernet.h>
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
  if ( Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
The mac[] array must be changed according to the MAC address of your Intel Galileo. It’s usually shown on a white label on the top of the Ethernet connector or on the bottom of the board.

What’s New with Ethernet API and Intel Galileo

In the case of Intel Galileo, considering we have a real operational system running with Quark SoC that supports Ethernet interfaces, the Ethernet class is because the interface might be configured directly on the Linux context.
This brings a performance improvement, especially when a DHCP connection is being used. Otherwise, every time the sketch runs, the Ethernet class checks if the interface is configured. If it’s not, the DHCP negotiation process is restarted, which takes time.
Nothing blocks you from using the Ethernet class, but in case of Intel Galileo boards, once the Ethernet interface is already configured on the Linux scope, this class becomes irrelevant.
It’s also not necessary to hard code the MAC address in the sketches, which makes your sketches more flexible on different boards.

Ethernet Example: Network Time Protocol (NTP)

The IDE includes several sketches that use the Ethernet API. They can be accessed by choosing File ➤ Examples ➤ Ethernet.
The examples are from regular Arduino IDE and several sketches have comments in the code referring to Ethernet as a shield that must be ignored. One sketch example in particular, TwitterClient, will not work because Twitter changed the API with the OAuth methods discussed and resolved in Chapter 6.
Among the sketches presented, there is a sketch (choose File ➤ Examples ➤ Ethernet ➤ UdpNtpClient) that implements a simple UDP client that displays the Network Time Protocol (NTP) in the IDE serial console.
Listing 5-4 shows the source code.
Listing 5-4. WiFiUdpNtpClient.ino
/*
  Udp NTP Client
Get the time from a Network Time Protocol (NTP) time server
Demonstrates use of UDP sendPacket and ReceivePacket
For more on NTP time servers and the messages needed to communicate with them,
Warning: NTP Servers are subject to temporary failure or IP address change.
Plese check
if the time server used in the example didn't work.
created 4 Sep 2010
by Michael Margolis
modified 9 Apr 2012
by Tom Igoe
This code is in the public domain.
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
  0x98, 0x4f, 0xee, 0x01, 0x4c, 0x44 };
unsigned int localPort = 8888;      // local port to listen for UDP packets
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov NTP server
// IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov NTP server
// IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov NTP server
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  // start Ethernet and UDP
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  Udp.begin(localPort);
}
void loop()
{
  sendNTPpacket(timeServer); // send an NTP packet to a time server
  // wait to see if a reply is available
  delay(1000);
  if ( Udp.parsePacket() ) {
    // We've received a packet, read the data from it
    Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    Serial.print("Seconds since Jan 1 1900 = " );
    Serial.println(secsSince1900);
    // now convert NTP time into everyday time:
    Serial.print("Unix time = ");
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;
    // print Unix time:
    Serial.println(epoch);
    // print the hour, minute and second:
    Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
    Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs per day)
    Serial.print(':');
    if ( ((epoch % 3600) / 60) < 10 ) {
      // In the first 10 minutes of each hour, we'll want a leading '0'
      Serial.print('0');
    }
    Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
    Serial.print(':');
    if ( (epoch % 60) < 10 ) {
      // In the first 10 seconds of each minute, we'll want a leading '0'
      Serial.print('0');
    }
    Serial.println(epoch %60); // print the second
  }
  // wait ten seconds before asking for the time again
  delay(10000);
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress & address)
{
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket();
}
Connect your Intel Galileo board using the Ethernet cable to the router in a port that can establish a DHCP connection, or to a computer that shares the Internet connection.
Change the mac[] array with the MAC address of your Intel Galileo board. Observe the white tag at the top of the Ethernet connector or at the bottom of your board.
With the cable properly connected, run the sketch and open the IDE serial console by using Tools ➤ Serial Monitor or pressing CTRL+SHIFT+M.

Reviewing WiFiUdpNtpClient.ino

This section simply provides a general explanation as to how the Ethernet API is used.
If you are interested in how NTP works and how to implement a client using UDP, visit http://www.ietf.org/rfc/rfc958.txt and http://en.wikipedia.org/wiki/Network_Time_Protocol .
The code initially includes two headers, which are necessary to establish the Ethernet setting and use the UDP datagrams:
#include <Ethernet.h>
#include <EthernetUdp.h>
The mac[] array defines the MAC address that must match the MAC address of your board.
The timerServer and Udp instances are created to point to the NTP server and provide access to UDP datagrams’ functions, respectively:
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov NTP server
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
In the setup() function, the Ethernet interface is configured with Ethernet object and the Udp instance is initialized with localport (8888).
unsigned int localPort = 8888;      // local port to listen for UDP packets
...
...
...
  // start Ethernet and UDP
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  Udp.begin(localPort);
In the loop() function, the function sendNTPpacket() is called and passes the server address through the timeServer object. The sendNTPpacket() function is implemented by the sketch and it is not part of the Ethernet API.
In the sendNTPpacket(),Udp sends a datagram to timeServer using port 123 and an NTP request. Note that the mechanism is similar to how Wire API sends I2C commands. beginPacket() initiates to the server and port, write() stacks packages to be sent, and endPacket() transmits the outgoing data. The write() method must always be wrapped between beginPacket() and endPacket().
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
After sendNTPpacket() is called, the response is received by the parsePacket() method of the Udp instance.
Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
The rest of the code parses the response and, using the Serial object, displays the results every 10 seconds provided by the delay() function at the end of loop() function.
You should see something like this in the output:
Seconds since Jan 1 1900 = 3614060697
Unix time = 1405071897
The UTC time is 9:44:57
Seconds since Jan 1 1900 = 3614060708
Unix time = 1405071908
The UTC time is 9:45:08
Seconds since Jan 1 1900 = 3614060719
Unix time = 1405071919
The UTC time is 9:45:19

Dynamic and Static IP Using Ethernet

This section describes the process for connecting Intel Galileo to a router or computer. One important point regarding connecting Intel Galileo to a personal computer is that most people use this kind of connection only to transfer files via scp or ftp, but in this section, you will learn how to use it for Internet access as well.
The connection to your router or computer depends on the network configuration you use. Both offer ways to reach the boards and access the Internet and computers.
As mentioned, you can configure the Ethernet interface using Linux and the Ethernet.begin() method can be removed from the sketches without any problems. The interface can be configured manually, using the Linux serial console, persisted in the configuration of the network, or even through sketches.
The Ethernet adapter present in the Intel Galileo boards is identified in Linux as interface eth0. The next sections explain how to configure the IP on Linux for dynamic and static connections.
However, it is necessary to know how your router is configured in order to understand the range of IPs used as dynamic IPs, the range for the static IPs, the IP mask, and the gateway used.
Your routers can be accessed by typing 192.168.1.1 in the address box of a browser. A password and username are required; the username and password are usually admin. If that does not work, you can try to reset your router to the default settings (check your router manual).
From the router settings, you will be able to see which IP range is configured for DHCP and which range is set for static IPs.
Most routers use the 192.168.1.X range for dynamic IPs, where X is a number above 100 (static IPs use numbers below 100). There are also reserved addresses. For example, 192.168.1.1 is often used to provide the configuration for the web interface and 192.168.1.2 and 192.168.1.15 usually provide the Ethernet connection through a USB if your router contains a USB port. Again, these addresses depend on your router.
There are thousands of network configurations that affect how your Intel Galileo must be configured, so this section assumes you have a laptop connected to a router using WiFi and you have an Ethernet adapter.

Dynamic IP (DHCP)

It is possible to connect Intel Galileo with a dynamic IP to a router or computer, but it is necessary to create two configurations—one for Intel Galileo and the other for the computer or router. The next sections explain how to create such configurations.
Configuring Intel Galileo for Dynamic IP
By default, the Intel Galileo software supports dynamic IPs obtained by the DHCP (Dynamic Host Configuration protocol). You can check this configuration in the /etc/network/interfaces file in the following lines:
# Wired or wireless interfaces
auto eth0
iface eth0 inet dhcp
iface eth1 inet dhcp
The eth1 is totally irrelevant because Intel Galileo supports only one Ethernet adapter.
With this configuration set, you simply connect your cable to your router or to a computer that shares the Internet connection.
You can bring the interface down by using the terminal console and typing ifdown eth0 and bring it back up by typing ifup eth0.
Testing Intel Galileo with a Router Using DHCP
If /etc/network/interfaces is configured for DHCP as mentioned, you just need to connect Intel Galileo and your router using the Ethernet cable.
If you have a Linux serial console, you might be a message like this when you connect the cable:
[10737.520194] libphy: stmmac-1:01 - Link is Up - 100/Full
[10737.525495] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
You can then try to ping your computer IP or ping some valid server on the Internet. For example:
root@clanton:/etc# ping www.google.com
PING www.google.com (74.125.224.52): 56 data bytes
64 bytes from 74.125.224.52: seq=0 ttl=57 time=17.777 ms
64 bytes from 74.125.224.52: seq=1 ttl=57 time=18.588 ms

Static IPs

Sometimes the router is far from Intel Galileo and extending a cable to your router is not an option. If your computer is closer and provides an Ethernet port to connect Intel Galileo, this is a good solution.
You can specify a static IP to Intel Galileo using the local connection in your computer to transfer files. You can even go a little bit beyond by allowing your computer to share its Internet connection with Intel Galileo.
If you choose to make your computer share its Internet connection, you need to determine which adapter will be used to connect to Intel Galileo and identify the adapter that will share the connection. For example, suppose you have a local connection in your computer that’s used to connect Intel Galileo via the Ethernet cable and you have a wireless adapter that connects your computer to a router that gives you access to the Internet. What you need to do is tell your computer that this wireless adapter will share the Internet connection with the local connector, which indirectly tells Intel Galileo to use the Internet as well.
The only problem is that this configuration must be done in your computer and the process varies according to the operation system. The following sections use the most common operation systems—Windows 7, Ubuntu 12.04, and MACOSX 10.06—as examples.
Configuring on Windows 7
The configuration on Windows is a little bit odd. You have to change or create a local connection and configure IPv4 as the static IP. Then, using the adapter that provides the Internet connection, you tell this adapter that the “local connection” will use its Internet access. The procedure is as follows:
1.
Access the Control Panel by choosing Control Panel ➤ Network and Internet ➤ Network and Sharing Center.
 
2.
Click on Change Adapter Settings and right-click on Local Area Connection. The Local Area Connection Properties will be shown, as shown in Figure 5-6.
 
3.
Select Internet Protocol Version 4 (TCP/IPv4) and click the Properties button. The IPv4 setting will be shown, as shown in Figure 5-7. Add a valid static IP, subnet mask, and gateway (usually your router IP).
 
4.
In this case, IPv4 was set to the Google DNS servers 8.8.8.8 and 8.8.4.4, but you can change this to the servers of your preference.
 
5.
The subnet mask must be the same as your router, otherwise this connection will be out of the common network. If you do not know the subnet mask your Internet adapter is using, you can access it using the ipconfig command in the Windows commands shell. For this, click the Start icon or press the Windows key https://static-content.springer.com/image/chp%3A10.1007%2F978-1-4302-6838-3_5/MediaObjects/978-1-4302-6838-3_5_Figaa_HTML.jpg , and then type cmd and press Enter to open the Windows command shell. In the shell, type ipconfig and press Enter. Figure 5-8 shows the output of the ipconfig command on my computer.
 
6.
In this case, the adapter that shares the Internet is the Wireless Lan Adapter and the subnet mask is 255.255.255.0. You need to determine the right adapter on your computer. If your intention is to have only a static IP, this is the last step. You can move on to the section entitled “Configuring Intel Galileo for Static IP” in this chapter. Otherwise, continue reading!
 
7.
To share the Internet connection, access your adapters again by choosing Control Panel ➤ Network and Internet ➤ Network and Sharing Center and clicking Change Adapter Settings. But now, right-click in the adapter of your computer that provides Internet access to you and select Properties. Then click in the Sharing tab and check the option to share the Internet in the listbox. Figure 5-9 shows an example that uses a wireless adapter to access the Internet and a Local Area Connection for Intel Galileo.
 
Windows might show you a message saying that some other static IP will be associated with your local connection. This happens because Windows reserved some IPs for sharing, as shown in Figure 5-10.
Just accept the new IP and connect the Ethernet cable to Intel Galileo and to your computer.
8.
At this point, Windows is ready to establish a local connection to Intel Galileo. The last step is to configure Intel Galileo for static IPs. Read the section entitled “Configuring Intel Galileo for Static IPs.”
 
Configuring on Ubuntu 12.04
It’s quite easy to establish an IP connection on Ubuntu and make this connection offer Internet access to Intel Galileo connected via Ethernet. The following steps illustrate an example using WiFi (wlan0) to access the Internet and an Ethernet interface (eth0) to connect to Intel Galileo.
The procedure is:
1.
Access Dash using the Super or Windows key https://static-content.springer.com/image/chp%3A10.1007%2F978-1-4302-6838-3_5/MediaObjects/978-1-4302-6838-3_5_Figa_HTML.jpg .
 
2.
Start typing the word network. You will soon be able to see Network Connections, as shown in Figure 5-11. Click on it.
 
3.
From the Wired tab, select the wired connection and click the Edit button, as shown in Figure 5-12.
 
4.
At this point, you need to determine whether you want a static IP only or a static IP with Internet access. If you need Internet access, go to Step 5. Otherwise, move to Step 7. Ubuntu is a little bit tricky in how it deals with IPv4 settings.
 
5.
Change the IPv4 settings as follows: change Method to Shared to Other Computers and check the Available to All Users checkbox. Save the changes by clicking Save. Figure 5-13 shows how these settings must be made.
 
  • You might wonder why you did not specify the IP, subnet mask, gateway, and all other elements. It is because you will use a shared Internet, so Ubuntu will update the route table with the resource that provides the Internet access and a fixed IP determined by Ubuntu will be provided. The IP provided by Ubuntu must be the gateway to be used on Intel Galileo. Keep this information in mind and move to Step 7.
6.
This step is used when you need only a static IP without Internet access. Change the IPv4 properties by specifying an IP for your local connection, a subnet mask, a gateway (usually your router IP, such as 192.168.1.1) and the DNS servers. Figure 5-14 shows this configuration using the Google DNS servers 8.8.8.8 and 8.8.4.4.
 
7.
Power on Intel Galileo and connect to the computer using the Ethernet cable. In few seconds, the wired connection will be ready.
 
8.
Open a Linux terminal shell on Ubuntu by pressing CTRL+ALT+T and typing ifconfig eth0 to check the configuration that Ubuntu gave to your eth0.
 
If you selected a shared Internet connection, you probably will see the static IP that Ubuntu provided. Otherwise you will see the IP that you configured in Step 6.
mcramon@mcramon-ThinkPad-T520:/media/F42E-D989$ ifconfig eth0
eth0      Link encap:Ethernet HWaddr 3c:97:0e:15:67:91
          inet addr:10.42.0.1 Bcast:10.42.0.255 Mask:255.255.255.0
          inet6 addr: fe80::3e97:eff:fe15:6791/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
          RX packets:38 errors:0 dropped:0 overruns:0 frame:0
          TX packets:208 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:7616 (7.6 KB) TX bytes:36586 (36.5 KB)
          Interrupt:20 Memory:f2500000-f2520000
9.
At this point, your Ubuntu is ready to establish a local connection with Intel Galileo. The last step is to configure Intel Galileo for a static IP. Read the section “Configuring Intel Galileo for Static IPs” to learn how to do so.
 
A Common Problem with Ubuntu and Multiple Adapters
If you are losing your Internet connection on Ubuntu when the Ethernet cable is connected to Intel Galileo and its properly powered on, it means you have a masquerading problem with your IP route (MASQ). To fix this issue, open a Ubuntu command shell and type the following (this code assumes wlan0 is the adapter that gives you access to the Internet and the local adapter used to connect Intel Galileo is eth0):
sudo -i
echo 1 > /proc/sys/net/ipv4/ip_forward
/sbin/iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
/sbin/iptables -A FORWARD -i wlan0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A FORWARD -i eth0 -o wlan0 -j ACCEPT
Then remove your Ethernet cable and reconnect. After a few seconds, when the local connection is re-established, try to ping Intel with the ping www.intel.com command to test whether your Internet is working.
Configuring on MacOSX 10.0
It’s quite easy to set up an IP connection on a Mac and make this connection offer Internet access to Intel Galileo connected via Ethernet. The first thing you need to do is determine if your Mac has an Ethernet adaptor. If it doesn’t, you need to order one. One example of such an adapter is the Thunderbolt to Gigabit Ethernet adapter, which costs around $30 and is shown in Figure 5-15.
There are other more affordable adapters in the market that use the USB interface, but considering the limited number of USB ports on the Mac and the stability offered by this product, it is the best choice in my opinion.
The steps to set a static IP with an Internet connection are as follows:
1.
Disconnect the Ethernet cable.
 
2.
Click on System Preferences and then on Network.
 
3.
Change the Configure IPv4 listbox to Manually and then add the IP address, the subnet mask, and the gateway. Note that the gateway is named Router. Figure 5-16 shows an example.
 
4.
Click on Advance and select the DNS tab to configure the DNS server, as shown in Figure 5-17.
 
5.
Connect Intel Galileo to your Mac using the Ethernet cable. You should be able to see the cable with its Status changed to Connected, as shown in Figure 5-18.
 
At this point, the setting needed to transfer files between Intel Galileo and the Mac is ready. If you do not want to share the Internet connection, you can move to the “Configuring Intel Galileo for Static IP" section. Otherwise, if you want Internet access on Intel Galileo through your Mac, continue to Step 6.
6.
It’s easy to share the Internet connection between different adapters on a Mac. Using the Apple menu, choose System Preferences and select Internet Sharing. Then select the adapter that will share the Internet connection and the adapter that will receive the sharing. For example, Figure 5-19 shows the WiFi adapter on MacOSX sharing the Internet connection with the Ethernet adaptor, wherein Intel Galileo is connected.
 
Configuring Intel Galileo for Static IP
If you read the previous section, your computer is ready to connect Intel Galileo as a local connection via an Ethernet cable.
The static IP can be set manually using the command line. It is possible to persist the configuration after booting up and it can be configured using sketch. In the same way that the /etc/network/interfaces file is used to configure the DHCP connection, it is also used to configure the static IP.
It is recommended that you test the configuration using the command line before you persist the /etc/network/interfaces .
The next sections describe these methods.
Programming the IP with Intel Galileo’s Linux Console
Using the ifconfig command, type the valid IP address to be configured in your network and enter the right subnet mask.
root@clanton:∼# ifconfig eth0 192.168.1.27 netmask 255.255.255.0 up
Note if you use Ubuntu with a shared Internet, it is necessary to specify a static IP in the same network group of the IP that’s automatically provided. For example, in Step 8 of the “Ubuntu 12.04” section, the IP was 10.42.0.1, so try to provide an IP close to this, such as 10.42.0.2.
Try to ping your computer using the static IP that your computer is using. If the ping fails, see if you need to include the gateway also.
For example, suppose your gateway is 192.168.1.1. Try the following procedure:
1.
Check your route using the route command:
 
root@clanton:∼# route
Kernel IP routing table
Destination     Gateway    Genmask         Flags  Metric Ref   Use Iface
192.168.1.0     *          255.255.255.0   U      0      0     0   eth0
2.
If the gateway is not specified, add a default route to it. Use the route command again:
 
root@clanton:∼# route add default gw 192.168.1.1 netmask 255.255.255.0
3.
Check if the route was added successfully:
 
root@clanton:∼# route
Kernel IP routing table
Destination    Gateway       Genmask         Flags  Metric Ref  Use  Iface
default        192.168.1.1   255.255.255.0   UG     0      0    0    eth0
192.168.1.0    *             255.255.255.0   U      0      0    0    eth0
4.
Try to ping your computer. Suppose your computer uses the IP 192.168.1.22 for the local connection:
 
root@clanton:∼# ping 192.168.1.22
PING 192.168.1.22 (192.168.1.22): 56 data bytes
64 bytes from 192.168.1.22: seq=0 ttl=128 time=3.018 ms
64 bytes from 192.168.1.22: seq=1 ttl=128 time=1.795 ms
64 bytes from 192.168.1.22: seq=2 ttl=128 time=1.879 ms
If you are able to ping your computer, your configuration is fine and you can persist this configuration in /etc/network/interfaces .
Persisting the Static Configuration
The static IP configuration can be done in the file /etc/network/interfaces .
Using the Linux command console, open this file (you can use vi) and replace the following lines:
auto eth0
iface eth0 inet dhcp
iface eth1 inet dhcp
Replace the IPs with the IP of your interest:
auto eth0
iface eth0 inet static
address 192.168.1.27
netmask 255.255.255.0
gateway 192.168.1.1
You can restart the network configuration using the following command:
root@clanton:∼# /etc/init.d/networking restart
Or you can reboot Intel Galileo using the reboot command. Try to ping your computer or router. If it does not work, try to configure the connection manually, as explained in the previous section, in order to understand what’s wrong with the configuration.
Configuring the IP via Sketch
The configuration of IP using sketch it is quite simple. Since Intel Galileo is powered by a Linux OS, it is possible to use functions that make system calls, for example, system and popen.
Listing 5-5 shows an example of how to configure the IP statically using system calls.
Listing 5-5. configure_static_ip.ino
void setup() {
  // put your setup code here, to run once:
system("ifconfig eth0 192.168.1.28 netmask 255.255.255.0 up");
system("route add default gw 192.168.1.1 netmask 255.255.255.0");
}
void loop() {
  // put your main code here, to run repeatedly:
}
This code is so simple that does not need a review section. The system call exactly the same commands explained in the section "Programming the IP with Intel Galileo's Linux console".

Simplifying the Sketches by Removing the Ethernet Objects

As mentioned, the Ethernet API was created for Ethernet shields. In Intel Galileo, if the interface eth0 is configured on a Linux context, the Ethernet object becomes useless.
For example, suppose you have you IP configured on Intel Galileo Linux and your computer is also sharing the Internet access to Intel Galileo. Then you decide to run the example in Listing 5-4 and remove or comment out the Ethernet object from the code. In this case, the setup() function will look like this:
void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
/* THIS CODE IS COMMENTED!!! REMOVED FROM THE LOGIC!!!!
   Ethernet object is not being used!!!!
  // start Ethernet and UDP
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
*/
  Udp.begin(localPort);
}
You can compile the example again, and with the Internet working on Intel Galileo, the example runs without problems. Thus, the Ethernet object is useless when the IP is already configured on Linux.
The sketch will work not with the Ethernet object.

Transferring Files Between Intel Galileo and Computers

This section describes how to transfer files between an Intel Galileo board and your computers through a TCP/IP connection, SD card, or USB pen drive.
If you have an IP configured using the procedures mentioned in this chapter, you will be able to transfer files using secure copy (scp) or ftp. It doesn’t matter if the adaptor is a mini-PCIe WiFi card or simply an Ethernet cable, you simply need to provide the IP on Intel Galileo and determine if this IP is achievable on your computer.
If you are using WiFi, check the IP using the Linux terminal shell and typing ifconfig wlan0. If you are using an Ethernet cable, you can check it by typing ifconfig eth0. The previous sections in this chapter explain the procedures you need to follow to have a functional IP using WiFi or Ethernet.

Using ftp

After you set the IP on your Intel Galileo it is necessary to start the ftpd deamon. To use the ftp with a standard port, type the following command into the Linux terminal shell: tcpsvd 0 ftp ftpd -w &. For example, suppose you want to establish a static IP and start the ftp deamon:
root@clanton:∼# ifconfig eth0 192.168.1.27 netmask 255.255.255.0 up
root@clanton:∼# tcpsvd 0 ftp ftpd -w &
On your computer using a terminal shell, you can use the ftp and pass the Intel Galileo IP using root as the username:
C:\Users\mcramon> ftp 192.168.1.27
Connected to 192.168.1.27.
220 Operation successful
User (192.168.1.27:(none)): root
230 Operation successful
After this, you can transfer files between your computer and Intel Galileo using the regular ftp commands. For example, suppose you want to extract a binary file called a.bin, which is located in /home/root on Intel Galileo:
ftp> bin
200 Operation successful
ftp> get a.bin
200 Operation successful
150 Opening BINARY connection for a.bin (3 bytes)
226 Operation successful
If, for some reason, you want to change the ftp deamon port to something, you just need to change the standard port (called port in the command) to the specific port you want. For example, if you want to start the ftpd deamon using the port 1080, but you already have a ftp deamon running, you can kill the deamon and start a new one by specifying the new port:
root@clanton:∼# kill -9 $(pidof tcpsvd)
root@clanton:∼# tcpsvd 0 1080 ftpd -w &
Note that ftp, which represents the standard port number 21, is replaced by 1080.

Using scp or pscp

If you are a Linux or MacOSX user, you can transfer files using scp tool.
If you are a Windows user, you can install a free software program called pscp.exe, which is similar to the scp tool. The installation of pscp.exe on Windows is described in the section “Tools to Be Used (Needed on Windows Only)” when an example of hacking involving the IDE is discussed. Follow the procedure to download and copy the pscp.exe file to your preferable directory.
By default, once you have an IP established on your Intel Galileo and the IP is reachable by your computer (test it using the ping command), you simply use scp or pscp. For example, imagine you have a static IP of 192.168.1.27 set on your board and you want to transfer a file named test.txt to the /home/root directory on your Intel Galileo. The commands to be used on the Linux command shell are as follows.
  • On Linux or MacOSX:
mcramon@mcramon-ThinkPad-T520:$ scp test.txt root@192.168.1.27:/home/root/ .
  • On Windows with pscp.exe installed:
C:\Users\mcramon\tools> pscp -scp test.txt root@192.168.1.27:/home/root/.
test.txt | 0 kB | 0.0 kB/s | ETA: 00:00:00 | 100%
Note that there is a slight difference in the command syntax between pscp and scp. On Windows, pscp.exe requires that the protocol be specified. That’s why -scp is the first argument when the tool is invoked.

Using an SD Card

It’s possible to transfer files using an SD card even if you are running an SD image.
Your SD card must be formatted as FAT or FAT32. Accessing the files in the SD card depends on if you are using an SPI image or an SD card image on Intel Galileo.

SPI Images with SD Card Inserted on Demand

If you are using an SPI image instead of an SD card image, as soon you connect your SD card, the device will be mounted and it will be accessible from /media/mmcblk0p1.
You can confirm this by typing fdisk -l into the Linux terminal shell:
root@clanton:/media/mmcblk0p1# fdisk -l
Disk /dev/mmcblk0: 3965 MB, 3965190144 bytes
49 heads, 48 sectors/track, 3292 cylinders
Units = cylinders of 2352 * 512 = 1204224 bytes
Device Boot      Start        End    Blocks    Id  System
/dev/mmcblk0p1       4       3293    3868160    b  Win95 FAT32
If you enter the /media/mmcblk0p1 folder, the files from your SD card will be there. For example:
root@clanton:/media# cd /media/mmcblk0p1/
root@clanton:/media/mmcblk0p1# ls
test.txt

SD Card Image

If you are using an SD card image, you can include on the SD card the kernel, sysimage, grub, and all files needed to make your Intel Galileo boot from the SD card.
In this case, you need to access the /media/realroot folder.
For example, suppose you have a file called HI_I_AM_NEW_FILE.txt in the root of the SD card that you will use as the SD image. If you access /media/realroot, you will see something like this:
root@clanton:/ # cd /media/realroot/
root@clanton:/media/realroot# ls
HI_I_AM_NEW_FILE.txt
boot
bzImage
core-image-minimal-initramfs-clanton.cpio.gz
grub.efi
image-full-galileo-clanton.ext3
With all the files accessible, you can copy them to any other folder using the regular cp command.

Using a USB Pen Drive

If you have an Intel Galileo Gen 2, you can connect a USB pen drive directly to the OTG USB port. However, if you have the first generation of Intel Galileo, you need to use a micro USB to USB 2.0 OTG adapter, as shown in Figure 5-20.
If you need such an adapter, do not buy one in an “L” shape because, if you are using the serial audio jack cable, the adapter will press against the audio jack and might damage your board.
With the adapter in place, you can connect the USB pen drive and see messages like these from the Linux terminal shell:
root@clanton:∼# [ 3691.870165] usb 2-1: new high-speed USB device number 2 using ehci-pci
[ 3692.043645] scsi0 : usb-storage 2-1:1.0
[ 3693.128613] scsi 0:0:0:0: Direct-Access     Kingston DataTraveler 109 PMAP PQ : 0 ANSI: 0 CCS
[ 3693.171753] sd 0:0:0:0: Attached scsi generic sg0 type 0
[ 3694.815187] sd 0:0:0:0: [sda] 15240576 512-byte logical blocks: (7.80 GB/7.26 GiB)
[ 3694.827134] sd 0:0:0:0: [sda] Write Protect is off
[ 3694.834139] sd 0:0:0:0: [sda] No Caching mode page present
[ 3694.839721] sd 0:0:0:0: [sda] Assuming drive cache: write through
[ 3694.855254] sd 0:0:0:0: [sda] No Caching mode page present
[ 3694.860912] sd 0:0:0:0: [sda] Assuming drive cache: write through
[ 3694.891920]  sda: sda1
[ 3694.906548] sd 0:0:0:0: [sda] No Caching mode page present
[ 3694.912207] sd 0:0:0:0: [sda] Assuming drive cache: write through
[ 3694.918365] sd 0:0:0:0: [sda] Attached SCSI removable disk
You can also check with fdisk -l, as follows:
root@clanton:/media/realroot# fdisk -l
Disk /dev/mmcblk0: 3965 MB, 3965190144 bytes
49 heads, 48 sectors/track, 3292 cylinders
Units = cylinders of 2352 * 512 = 1204224 bytes
Device Boot      Start     End       Blocks   Id   System
/dev/mmcblk0p1       4     3293     3868160    b   Win95 FAT32
Disk /dev/sda: 7803 MB, 7803174912 bytes
122 heads, 58 sectors/track, 2153 cylinders
Units = cylinders of 7076 * 512 = 3622912 bytes
Device  Boot    Start       End      Blocks  Id   System
/dev/sda1 *         2       2154    7616256   b   Win95 FAT32
This code indicates that Intel Galileo recognized your USB pen drive and the content can be accessed in the /media/sda1 folder. For example:
root@clanton:∼# cd /media/sda1/
root@clanton :/media/sda1# ls
NewFile1.jpg
NewFile1.png
NewFile2.jpg
NewFile2.png
NewFile3.png
NewFile4.png
NewFile5.png
NewFile6.png
NewFile7.png
poky-edison-eglibc-i686-edison-image-core2-32-toolchain-1.6
With all the files accessible, you can copy them to any other folder using the regular cp command.

Hacking the IDE to Improve the Sketch Transfer

Chapter 3 contains a section called “Troubleshoot with Drivers” that describes several workarounds and procedures for minimizing the problems with the Gadget serial driver, especially on Windows.
Besides the problem with drivers, Intel Galileo and Intel Galileo Gen 2 use an old protocol to transfer files called ZMODEM. So the IDE and the Intel Galileo boards talk to each other over a serial Gadget driver using the ZMODEM protocol.
This ZMODEM protocol is managed by two applications: lrz runs in the Intel Galileo boards and is used to received files with ZMODEM (the “r” on this case stands for “receive”) and lsz runs in the IDE and is used to send files with the ZMODEM protocol (the “s” stands for “send”).
These two software protocols are based on command lines and certain problems might occur during the file transfer. In order to manage the corner cases, an application called clloader runs like a deamon in the Intel board and manages the lrz tool. The same process happens on the IDE but there is only a script responsible for sending the file to the Intel Galileo board and for invoking the lsz.
Figure 5-21 shows a simplified stack of how these software protocols interact with other using the Gadget serial driver.
The problem is, even with the clloader application, the architecture that transfers the files is still poor because there is no real state machine implemented between the clloader and the script responsible for transferring from the IDE. When something fails, the serial hangs. This can force the IDE to close and reboot the computer.

How the Hacked IDE Works

If your Intel Galileo board has an IP that’s reachable from your computer, it is possible to make some changes to the IDE and program to transfer the files using TCP/IP. This brings a significant improvement in terms of stability because it reduces significantly the serials handling during the sketch transfer. The serial objects are still available without problems.
It does not matter if Intel Galileo is using a WiFi card or an Ethernet cable connected to the router or computer. If there is an IP available, it is possible to hack the IDE and improve the file transfer.
Before implementing these changes, you need to understand some details about how the IDE and Intel Galileo boards work. Take a look at the new mechanism proposed in Figure 5-22.

Configuring the Sketch Transfer

The next steps explain the changes that must be done to the board and to the IDE.
  • Changes to the board:
    1.
    When clloader receives the sketch transmitted by the IDE, the sketches are renamed sketch.elf and saved in the /sketch directory.
     
    2.
    The galileo_sketch_reset_script.sh script is located in /opt/cln/galileo/. It sends a signal to Linux, forcing sketch.elf to restart.
     
  • Changes to the IDE:
    1.
    The IDE contains some text files with the platform*.txt moniker for each operational system that contains information as to which software protocol is responsible for uploading the sketch to the board, the compiler to be used and the directives used in the compilation. They are located in the ...\arduino-1.5.3\hardware\arduino\x86 directory relative to your IDE installation. The files are as follows:
     
    • platform.linux.txt is used with Linux 32 OS bits.
    • platform.linux64.txt is used with Linux 64 OS bits.
    • platform.osx.txt is used with MacOSX.
    • platform.win.txt is used with Windows OS.
Among compilation directives and compilers to be used, these files tell the IDE which tool or script must be used to upload the files, as well as the pattern (arguments) passed to this tool.
Thus, when the IDE is started, the file that corresponds to the operational system is opened and the IDE is properly configured.
When the user asks the IDE to upload the sketch in the board, the scripts in this file will be responsible for the transfer; they call the lsz tool as explained.

Hacking the Transfers

Now that you understood the files you must change in the IDE and what the board does when the sketches are received, the changes are quite simple. However, it’s necessary to prepare your desktop with the tools required to make this hack possible.
If you are a MacOSX or Linux user, you do not need to download any tool. If you are a Windows user, you need to download some free tools.
After you have all the tools you need, you must make changes to the platform files, as explained next.

Tools to Be Used (Needed for Windows Only)

As you can see in Figure 5-22, the files will be transferred using the SCP protocol. Remote commands are sent to the boards using ssl.
The SCP protocol can be used with the scp command-line tool on Linux and MacOSX. Unfortunately, it’s not available on Windows. However, there is a free tool called pscp.exe that works like the scp command-line tool.
The remote commands are sent using the SSL protocol, which can be used with the ssl command-line tool on Linux and MacOSX. Again, there is a free tool for Windows called plink.exe.
Both of these Windows tools can be downloaded from http://www.chiark.greenend.org.uk/∼sgtatham/putty/download.html . You need to place the pscp.exe and plink.exe files in the ...\ arduino-1.5.3\hardware\tools\x86\bin directory, relative to your IDE installation directory. Both tools do not require any installation; just download and move them to the right folder.
This folder is where most external tools are installed for the IDE. Figure 5-23 shows this directory on a Windows system, with all the other tools including lsz and some cygwin-related files present.
Recall that if you are a Linux or MacOSX user, you do not need to download an external tool.

Changes to the Platform Files

Open the platform file related to the operational system using your favorite test editor. For example, if you are a Windows user, you open the platform.win.txt file.
All platform files are similar because they contain the same configuration fields. The section that really matters is X86 Uploader/Programmers tools. The following lines are an example of the platform.win.txt file.
# X86 Uploader/Programmers tools
# -------------------
tools.izmirdl.cmd.path ={runtime.ide.path}/hardware/arduino/x86/tools/izmir/ clupload_win.sh
#todo: pass extra args to shell script
tools.izmirdl.upload.params.verbose=-vvvvvv
tools.izmirdl.upload.params.quiet=-q
tools.izmirdl.upload.pattern ={runtime.ide.path}/hardware/tools/x86/bin/bash --verbose  --noprofile {cmd.path} {runtime.ide.path}/hardware/tools/x86/bin {build.path}/{build.project_name}.elf {serial.port}
The tools.izmirdl.cmd.path field specifies the tool or scripts that will be used to upload the sketch. In Windows, a script called clupload_win.sh is used.
The tools.izmirdl.upload.pattern field specifies the pattern of command calls. In other words, it determines the arguments to be passed to the tool specified in tools.izmirdl.cmd.path and how they must be called.
Basically these two fields are critical for making this hack work.
If you open other platform files, you will see that these fields have minimal changes. For example, for Linux 64 bits the platform file is platform.linux64.txt, the script used to upload is clupload_linux.sh (same for Linux 32 bits), and it’s clupload_osx.sh for MacOSX.
The process for changing the platform files is the same for Linux 64 and 32 bits and MacOSX. It’s shown in the following lines:
# X86 Uploader/Programmers tools
# -------------------
tools.izmirdl.cmd.path="{runtime.ide.path}/hardware/arduino/x86/tools/izmir/ clupload_linux_and_osx_hacked.sh"
tools.izmirdl.upload.params.verbose=-vvvvvv
tools.izmirdl.upload.params.quiet=-q
tools.izmirdl.upload.pattern=/bin/bash --verbose  --noprofile {cmd.path} {build.path}/{build.project_name}.elf
The script used with Linux and MacOSX is the same (clupload_linux_and_osx_hacked.sh) and only one argument is used ({build.path}/{build.project_name}.elf), because there is no needed to indicate the path of an external tool, since ssh and scp are part of the Linux and MacOSX distributions.
With only one argument used, the script for Linux and MacOSX is simpler than for Windows:
#!/bin/bash
echo "starting download script"
echo "Args to shell:" $*
# ARG 1: Path of tools used to transfer and send remote commands
# ARG 2: Elf File to download
# ATTENTION: ADD HERE YOU IP
galileo_ip="10.42.0.2"
# cleaning the sketch in /sketch folder
ssh root@$galileo_ip 'rm /sketch/*;kill -9 $(pidof sketch.elf)'
#transfer using scp protocol
scp $1 root@$galileo_ip:/sketch/sketch.elf
#giving permission to be executed and reseting to start the sketch
ssh root@$galileo_ip 'chmod a+x /sketch/sketch.elf;/opt/cln/galileo/galileo_sketch_reset_script.sh'
#END!!
The changes name the platform files. In other words, a new script is created to transfer the files and the scripts use the respective command-line tools to transfer the files (scp or pscp.exe) and send remote commands (ssl or plink.exe).
The platform files are available in the code/hacked_platforms_files folder of this book. However, you need to change to the right IP address presented in the transfer scripts.
All hacked files can be found in the code/hacked_platforms_files folder of this chapter, including the platform files and upload scripts for Windows, Linux 32 and 64 bits, and MacOSX.

Practical Example of a Hack

The following hack uses Windows, which is basically the same as Linux and Mac.
Step 1: Changing the Platform File
The first step is to create a new script to replace the clupload_win.sh file with something else, such as with clupload_win_hacked.sh.
tools.izmirdl.cmd.path ="{runtime.ide.path}/hardware/arduino/x86/tools/izmir/ clupload_win_hacked.sh"
Imagine this script will receive two arguments—the path you have the tools installed and the sketch’s filename. The instruction you received a couple pages ago was to download them to the folder.
Changing the pattern field based on this, you have:
tools.izmirdl.upload.pattern ={runtime.ide.path}/hardware/tools/x86/bin/bash --verbose  --noprofile {cmd.path} {runtime.ide.path}\hardware\tools\x86\bin {build.path}/{build.project_name}.elf
Stripping this line, you have:
  • {runtime.ide.path}/hardware/tools/x86/bin/bash: No changes here. This line is kept because it is the bash that will call the script.
  • --verbose  --noprofile: No changes here either. This line is kept to keep verbose when bash invokes the script.
  • {cmd.path}: No changes. This is the path and script to be called. Basically, it’s a call to the path and script programmed by tools.izmirdl.cmd.path.
  • {runtime.ide.path}\hardware\tools\x86\bin: This is the first parameter in the script and basically is where the tools are installed (pscp.exe and plink.exe).
  • {build.path}/{build.project_name}.elf: This is the second parameter in the script and contains the sketch name with the .elf extension created by the IDE. This is the sketch that will be transmitted to the board.
If you still don’t understand, basically this line is doing something like the following pseudo-code:
bash <VERBOSE_OPTIONS> <SCRIPT_NAME> <WHERE_THE_TOOLS_ARE> <THE_SKETCH_TO_BE_TRANSMITTED>
For Linux and MacOSX, the changes are simple because they assume that the scp and ssh tools are already on the operational system, so it’s not necessary to specify the directory of an external tool. For example, the change to Linux 64-bit (file platform_linux64.txt) is:
# X86 Uploader/Programmers tools
# -------------------
tools.izmirdl.cmd.path="{runtime.ide.path}/hardware/arduino/x86/tools/izmir/ clupload_linux_and_osx_hacked.sh"
tools.izmirdl.upload.params.verbose=-vvvvvv
tools.izmirdl.upload.params.quiet=-q
tools.izmirdl.upload.pattern=/bin/bash --verbose  --noprofile {cmd.path} {build.path}/{build.project_name}.elf
As you can see, only the path to the sketch .elf file is passed to the script that will be uploaded.
Step 2: Creating the Hacked Script
The script will do exactly what Figure 5-22 shows. Listing 5-6 is an example of the clupload_win_hacked.sh file created for Windows.
Listing 5-6. clupload_win_hacked.sh
#!/bin/sh
echo "starting download script"
echo "Args to shell:" $*
# ARG 1: Path of tools used to transfer and send remote commands
# ARG 2: Elf File to download
# ATTENTION: ADD HERE YOU IP
galileo_ip="192.168.1.27"
# cleaning the sketch in /sketch folder
$1/plink root@$galileo_ip 'rm /sketch/*;kill -9 $(pidof sketch.elf)'
#transfer using scp protocol
$1/pscp -scp $2 root@$galileo_ip:/sketch/sketch.elf
#giving permission to be executed and reseting to start the sketch
$1/plink root@$galileo_ip 'chmod a+x /sketch/sketch.elf;/opt/cln/galileo/galileo_sketch_reset_script.sh'
#END!!
For Linux and MacOSX, the upload script is simpler because ssh and scp are called directly. The same script can be used for both operational systems, as you can see in Listing 5-7.
Listing 5-7. clupload_linux_and_osx_hacked.sh
#!/bin/bash
echo "starting download script"
echo "Args to shell:" $*
# ARG 1: Path of tools used to transfer and send remote commands
# ARG 2: Elf File to download
# ATTENTION: ADD HERE YOU IP
galileo_ip="10.42.0.2"
# cleaning the sketch in /sketch folder
ssh root@$galileo_ip 'rm /sketch/*;kill -9 $(pidof sketch.elf)'
#transfer using scp protocol
scp $1 root@$galileo_ip:/sketch/sketch.elf
#giving permission to be executed and reseting to start the sketch
ssh root@$galileo_ip 'chmod a+x /sketch/sketch.elf;/opt/cln/galileo/galileo_sketch_reset_script.sh'
#END!!
Step 3: Reviewing the Script
As programmed by the pattern field in the platform file, the first parameter is where the transfer and remote commands tools are installed and the second is the sketch with the full path.
You need to change the galileo_ip variable to your Intel Galileo IP address.
The current sketch is then removed and the sketch process is stopped from the board through remote commands. The rm command is used to remove the sketch.elf file and the kill command is used to kill the current sketch.elf process. The process ID is returned by the pidof command:
# cleaning the sketch in /sketch folder
$1/plink root@$galileo_ip 'rm /sketch/*;kill -9 $(pidof sketch.elf)'
The sketch is then transferred to the board:
#transfer using scp protocol
$1/pscp -scp $2 root@$galileo_ip:/sketch/sketch.elf
Finally, the sketch receives permission to be executed and is restarted:
#giving permission to be executed and reseting to start the sketch
$1/plink root@$galileo_ip 'chmod a+x /sketch/sketch.elf;/opt/cln/galileo/galileo_sketch_reset_script.sh'
Step 4: Running the Hacked IDE
First of all, if you have an IDE running, close it. The IDE reads the platform file changes only when they initially run, so do not expect the changes to the platform files and the new script created to be read dynamically.
Make sure you replace the platform file to the directory ...\arduino-1.5.3\hardware\arduino\x86.
Also make sure you set your Intel Galileo IP in the script and copy the script to the right directory. In this example, the script must be moved to the .../arduino-1.5.3\hardware\arduino\x86\tools\izmir directory.
Before you run the IDE, make sure the public keys were informed during an ssh (or plink.exe for Windows) connection. There is no way to accept the ssh connection from the IDE since it is necessary to confirm by pressing the Y key on the keyboard. For Linux and MacOSX, run ssh root@<INTEL GALILEO'S IP>. For Windows, run plink.exe root@<INTEL GALILEO'S IP>. If you are using Linux or MacOSX, you can modify the script and add the ssh call:
ssh -o "StrictHostKeyChecking no" root@<INTEL GALILEO'S IP>
With this command, the ssh connection will be accepted without prompting.
Run the IDE and select a sketch from the examples or choose some of your own sketches. Transfer to the board as you usually do with the IDE.
If everything was okay, you should see the output of bash script execution in the IDE, as shown in Figure 5-24.
Note that each arrow in the figure represents the execution of the hacked script.

Summary

This chapter is very important because it explained how to connect Intel Galileo with the computer and the Internet and increase the possibilities for creating projects that require external commands. It also explained how to send information to remote computers and devices, which helps Intel Galileo connect to the world.
You also learned how to use the WiFi and Ethernet API and how these APIs can be improved. You can simplify their usage with Intel Galileo when a static or dynamic IP is configured in the board.
This chapter also explained how to transfer files using ftp and scp. You learned about an alternative for transferring sketches. You can hack the IDE in order to transfer files using the secure copy protocol instead of using the old z-modem protocol handled by the clloader application, which is present in the BSP images. This significantly improves the stability of the IDE and the Intel Galileo boards.
Open Access This chapter is licensed under the terms of the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License (http://​creativecommons.​org/​licenses/​by-nc-nd/​4.​0/​), which permits any noncommercial use, sharing, distribution and reproduction in any medium or format, as long as you give appropriate credit to the original author(s) and the source, provide a link to the Creative Commons licence and indicate if you modified the licensed material. You do not have permission under this licence to share adapted material derived from this chapter or parts of it.
The images or other third party material in this chapter are included in the chapter’s Creative Commons licence, unless indicated otherwise in a credit line to the material. If material is not included in the chapter’s Creative Commons licence and your intended use is not permitted by statutory regulation or exceeds the permitted use, you will need to obtain permission directly from the copyright holder.
insite
INHALT
download
DOWNLOAD
print
DRUCKEN
Metadaten
Titel
Networking and Hacks
verfasst von
Manoel Carlos Ramon
Copyright-Jahr
2014
Verlag
Apress
DOI
https://doi.org/10.1007/978-1-4302-6838-3_5

Premium Partner