-
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
WiFi Cards
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
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) |
https://communities.intel.com/docs/DOC-22226
.
Checking if the WiFi Card Was Recognized
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)
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.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
/lib/firmware
folder and reboot the system.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.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.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
.ucode
extension. Move this file to the /lib/firmware
folder.mv iwlwifi-6000g2b-6.ucode /lib/firmware/.
reboot
command.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)
The WiFi API
http://arduino.cc/en/Reference/WiFi
.
Scanning the Wireless Networks
code
folder of this chapter because this example is part of your IDE./*
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;
}
}
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
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>
WiFi
object, the program checks if the WiFi card is in place:if (WiFi.status() == WL_NO_SHIELD)
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");
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);
}
setup()
function ends the call to the local function listNetworks()
, which is where the magic happens.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);
}
...
...
...
}
WiFi.RSSI()
, and WiFi.encryptionType()
are called and passed to the network index as references.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));
}
}
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;
}
}
Connecting to the WPA or WEB
ConnectWithWPA
. See Listing 5-2.ConnectWithWEP
. See Listing 5-3.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();
}
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();
}
#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
#include <WiFi.h>
char ssid[] = "
yourNetwork
"; // your network SSID (name)
char key[] = "D0D0DEADF00DABBADEAFBEADED"; // your network key
int keyIndex = 0; // your network key Index number
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
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
.[ 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
"wlan0: link becomes ready"
, which indicates that the wlan0
is ready to be used.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
setup()
function.if (WiFi.status() == WL_NO_SHIELD)
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");
1.1.0
. This method is useless with Intel Galileo.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);
}
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);
}
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
.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)
.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
Step 1: Setting Up the WiFi Connection
wlan0
. This interface will be mentioned several times in the terminal shell command lines.Persisted Connection with WPA
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
/etc/network/interfaces
file. You can edit this file directly in the command shell using the vi
editor.root@clanton:∼#
vi /etc/network/interfaces
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
/etc/wpa_supplicant.conf
, which you created with wpa_passphrase
, observing the wpa-conf /etc/wpa_supplicant.conf
field.Persisted Connection with WEP
/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.# /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
root@clanton:∼#
/etc/init.d/networking restart
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
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.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
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;
}
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.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.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.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.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.getLocalIP()
. If it is, the status WL_CONNECTED
is returned; otherwise, WL_IDLE_STATUS
is used.wlan0
interface once Linux can handle the connection.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;
}
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).Ethernet API
Ethernet
, EthernetClient
, EthernetUDP
, IPAddress
, and Server
. For details, visit
http://arduino.cc/en/reference/ethernet
.Ethernet
is the primary class used to configure the Ethernet adapter.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(;;)
;
}
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
Ethernet
class is because the interface might be configured directly on the Linux context.Ethernet
class, but in case of Intel Galileo boards, once the Ethernet interface is already configured on the Linux scope, this class becomes irrelevant.Ethernet Example: Network Time Protocol (NTP)
OAuth
methods discussed and resolved in Chapter 6./*
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();
}
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.Reviewing WiFiUdpNtpClient.ino
http://www.ietf.org/rfc/rfc958.txt
and
http://en.wikipedia.org/wiki/Network_Time_Protocol
.#include <Ethernet.h>
#include <EthernetUdp.h>
mac[]
array defines the MAC address that must match the MAC address of your board.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;
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);
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.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();
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
Serial
object, displays the results every 10 seconds provided by the delay()
function at the end of loop()
function.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
scp
or ftp
, but in this section, you will learn how to use it for Internet access as well.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.eth0
. The next sections explain how to configure the IP on Linux for dynamic and static connections.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).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.Dynamic IP (DHCP)
Configuring Intel Galileo for Dynamic IP
/etc/network/interfaces
file in the following lines:# Wired or wireless interfaces
auto eth0
iface eth0 inet dhcp
iface eth1 inet dhcp
eth1
is totally irrelevant because Intel Galileo supports only one Ethernet adapter.ifdown eth0
and bring it back up by typing ifup eth0
.Testing Intel Galileo with a Router Using DHCP
/etc/network/interfaces
is configured for DHCP as mentioned, you just need to connect Intel Galileo and your router using the Ethernet cable.[10737.520194] libphy: stmmac-1:01 - Link is Up - 100/Full
[10737.525495] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
root@clanton:/etc# ping
www.google.com
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
Configuring on Windows 7
ipconfig
command in the Windows commands shell. For this, click the Start icon or press the Windows key
, 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.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!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.Configuring on Ubuntu 12.04
wlan0
) to access the Internet and an Ethernet interface (eth0
) to connect to Intel Galileo.network
. You will soon be able to see Network Connections, as shown in Figure 5-11. Click on it.-
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.
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
.ifconfig eth0
to check the configuration that Ubuntu gave to your eth0
.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
A Common Problem with Ubuntu and Multiple Adapters
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
ping
www.intel.com
command to test whether your Internet is working.Configuring on MacOSX 10.0
Router
. Figure 5-16 shows an example.Configuring Intel Galileo for Static IP
/etc/network/interfaces
file is used to configure the DHCP connection, it is also used to configure the static IP./etc/network/interfaces
.
Programming the IP with Intel Galileo’s Linux Console
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
10.42.0.1
, so try to provide an IP close to this, such as 10.42.0.2
.192.168.1.1
. Try the following procedure:
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
route
command again:root@clanton:∼#
route add default gw 192.168.1.1 netmask 255.255.255.0
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
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
/etc/network/interfaces
.
Persisting the Static Configuration
/etc/network/interfaces
.
vi
) and replace the following lines:auto eth0
iface eth0 inet dhcp
iface eth1 inet dhcp
auto eth0
iface eth0 inet static
address 192.168.1.27
netmask 255.255.255.0
gateway 192.168.1.1
root@clanton:∼#
/etc/init.d/networking restart
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
system
and popen
.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:
}
"Programming the IP with Intel Galileo's Linux console"
.Simplifying the Sketches by Removing the Ethernet Objects
eth0
is configured on a Linux context, the Ethernet object becomes useless.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);
}
Ethernet
object.Transferring Files Between Intel Galileo and Computers
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.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
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
&
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
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
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
&
ftp
, which represents the standard port number 21, is replaced by 1080.Using scp or pscp
scp
tool.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.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%
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
SPI Images with SD Card Inserted on Demand
/media/mmcblk0p1
.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
/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
/media/realroot
folder.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
cp
command.Using a USB Pen Drive
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
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
/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
cp
command.Hacking the IDE to Improve the Sketch Transfer
ZMODEM
. So the IDE and the Intel Galileo boards talk to each other over a serial Gadget driver using the ZMODEM
protocol.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”).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
.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
Configuring the Sketch Transfer
-
Changes to the board:1.When
clloader
receives the sketch transmitted by the IDE, the sketches are renamedsketch.elf
and saved in the/sketch
directory.2.Thegalileo_sketch_reset_script.sh
script is located in/opt/cln/galileo/
. It sends a signal to Linux, forcingsketch.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.
-
lsz
tool as explained.Hacking the Transfers
Tools to Be Used (Needed for Windows Only)
ssl
.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.ssl
command-line tool on Linux and MacOSX. Again, there is a free tool for Windows called plink.exe
.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.lsz
and some cygwin
-related files present.
Changes to the Platform Files
platform.win.txt
file.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}
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.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.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.# 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
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.#!/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!!
scp
or pscp.exe
) and send remote commands (ssl
or plink.exe
).code/hacked_platforms_files
folder of this book. However, you need to change to the right IP address presented in the transfer scripts.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
Step 1: Changing the Platform File
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"
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
-
{runtime.ide.path}/hardware/tools/x86/bin/bash
: No changes here. This line is kept because it is thebash
that will call the script. -
--verbose --noprofile:
No changes here either. This line is kept to keepverbose
whenbash
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 bytools.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
andplink.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.
bash <VERBOSE_OPTIONS> <SCRIPT_NAME> <WHERE_THE_TOOLS_ARE> <THE_SKETCH_TO_BE_TRANSMITTED>
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
.elf
file is passed to the script that will be uploaded.Step 2: Creating the Hacked Script
clupload_win_hacked.sh
file created for Windows.#!/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!!
ssh
and scp
are called directly. The same script can be used for both operational systems, as you can see in Listing 5-7.#!/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
galileo_ip
variable to your Intel Galileo IP address.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)'
#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'
Step 4: Running the Hacked IDE
...\arduino-1.5.3\hardware\arduino\x86
..../arduino-1.5.3\hardware\arduino\x86\tools\izmir
directory.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>
ssh
connection will be accepted without prompting.Summary
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.