Troubleshooting
This troubleshooting chapter includes the following topics:

This section includes the following topics:

Problem: The ALE APIs do not display any client-specific data such as MAC addresses, IP addresses, and user names.
[root@ale ~]# /opt/ale/bin/feed-reader -f presence
Attempting to 'connect' to endpoint: tcp://localhost:7779
Connected to endpoint: tcp://localhost:7779
Subscribed to topic: "presence"
[1] Recv event with topic "presence"
seq: 55492
timestamp: 1453937605
op: OP_DELETE
topic_seq: 3522
source_id: 005056852F31
presence {
associated: true
hashed_sta_eth_mac: E62E7834EF4419D0BBF9DFC16B26BDD22E4D7B47
ap_name: POC-ALE-11-a7:78
radio_mac {
addr: 18:64:72:fa:77:90
}
}
[root@ale ~]# /opt/ale/bin/feed-reader -f location
Attempting to 'connect' to endpoint: tcp://localhost:7779
Connected to endpoint: tcp://localhost:7779
Subscribed to topic: "location"
[1] Recv event with topic "location"
seq: 56222
timestamp: 1453937752
op: OP_UPDATE
topic_seq: 36568
source_id: 005056852F31
location {
sta_location_x: 15.9103
sta_location_y: 92.6017
error_level: 48
associated: false
campus_id: FCCD5881918E3C8D8628130773403AA6
building_id: 659685E876A6325EB3F974FBBBA530F8
floor_id: 8B5207D8FDB1319AB35A72A32C7E5937
hashed_sta_eth_mac: E2F01DE79509D810D9C816C307C0024BD8540B9C
geofence_ids: EAD42871E6A53A1193CC243700FD4497
loc_algorithm: ALGORITHM_ESTIMATION
unit: FEET
}
Check: Is anonymization enabled on ALE?
Under Configuration > Options:
Figure 1 Anonymization Enabled
Disable anonymization on ALE by unchecking the Enable Anonymization knob and click on Apply. Verify that client MAC addresses are now visible in the ALE output feed.
[root@ale ~]# /opt/ale/bin/feed-reader -f presence
Attempting to 'connect' to endpoint: tcp://localhost:7779
Connected to endpoint: tcp://localhost:7779
Subscribed to topic: "presence"
[1] Recv event with topic "presence"
seq: 58026
timestamp: 1453938166
op: OP_DELETE
topic_seq: 3698
source_id: 005056852F31
presence {
sta_eth_mac {
addr: 92:68:c3:e4:23:18 <<<<<<-------------------------Station MAC addresses are now visible
}
associated: false
hashed_sta_eth_mac: 224738D5D14658BA35B3CAED07A4E959A2A07624
ap_name: POC-ALE-09-35:96
radio_mac {
addr: 18:64:72:e3:59:70
}
}
[root@ale ~]# /opt/ale/bin/feed-reader -f location
Attempting to 'connect' to endpoint: tcp://localhost:7779
Connected to endpoint: tcp://localhost:7779
Subscribed to topic: "location"
[1] Recv event with topic "location/50:87:89:bf:74:0c"
seq: 57993
timestamp: 1453938141
op: OP_UPDATE
topic_seq: 37935
source_id: 005056852F31
location {
sta_eth_mac {
addr: 50:87:89:bf:74:0c <<<<<<-------------------------Station MAC addresses are now visible
}
sta_location_x: 20.9299
sta_location_y: 84.8438
error_level: 35
associated: true
campus_id: FCCD5881918E3C8D8628130773403AA6
building_id: 659685E876A6325EB3F974FBBBA530F8
floor_id: 8B5207D8FDB1319AB35A72A32C7E5937
hashed_sta_eth_mac: 513941ED69088F1E7E6CC18D5CC63756CDCEEBA2
geofence_ids: EAD42871E6A53A1193CC243700FD4497
loc_algorithm: ALGORITHM_ESTIMATION
unit: FEET
}

Problem: The ALE feed-reader output does not display any location events.
[root@ale ~]# /opt/ale/bin/feed-reader -f location
Attempting to 'connect' to endpoint: tcp://localhost:7779
Connected to endpoint: tcp://localhost:7779
Subscribed to topic: "location"
Check 1: Does ALE generate any events at all?
[root@ale ~]# /opt/ale/bin/feed-reader
Attempting to 'connect' to endpoint: tcp://localhost:7779
Connected to endpoint: tcp://localhost:7779
Subscribed to topic: ""
Check 2: Is ALE receiving client RSSI feed from the controller/IAP?
If the source for client RSSI is AMON:
[root@ale ~]# /opt/ale/bin/feed-reader -e tcp://localhost:7778
Attempting to 'connect' to endpoint: tcp://localhost:7778
Connected to endpoint: tcp://localhost:7778
Subscribed to topic: ""
If the source for client RSSI is RTLS:
[root@ale ~]# /opt/ale/bin/feed-reader -e tcp://localhost:7777
Attempting to 'connect' to endpoint: tcp://localhost:7777
Connected to endpoint: tcp://localhost:7777
Subscribed to topic: ""
Check 3: Is the controller's physical IP correctly configured on ALE?
Only the physical/switch IP of the controller is recommended to be configured on ALE.
Check 4: Is the ALE IP address correctly configured on the controller/VC?
On the controller: Under Configuration > Management > Scroll down to the Analytics and Location Engines section > Verify whether an ALE entry is configured.
Figure 2 Analytics and Location Engines Configuration
On the IAP VC: Under VC homepage > Expand on More > Services > RTLS tab > Verify whether the Analytics & Location Engine knob is checked and the ALE IP address is configured.
Figure 3 Analytics & Location Engine and IP Address
Check 5: Is NTP correctly set up on ALE and the controller/IAP?
On ALE: Under Configuration > Options > NTP Server > Verify whether an IP address is configured for the NTP server. If not, specify one and click on Apply.
Check 6: Is ALE receiving data from the controller/IAP?
For AMON feed from the controller:
[root@ale ~]# tcpdump port 8211
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
00:01:41.424288 IP 10.70.20.252.8211 > 10.70.120.248.8211: UDP, length 1370
00:01:41.424848 IP 10.70.20.252.8211 > 10.70.120.248.8211: UDP, length 1370
00:01:41.425149 IP 10.70.20.252.8211 > 10.70.120.248.8211: UDP, length 1370
For RTLS feed from the controller, filter on the port that was configured on the controller and ALE. In the example below, port 8855 was used. The source IP addresses in the output correspond to traffic from different APs.
[root@ale ~]# tcpdump port 8855
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
19:49:18.387301 IP 10.70.20.203.fuscript > 10.70.120.248.8855: UDP, length 392
19:49:18.515666 IP 10.70.20.198.fuscript > 10.70.120.248.8855: UDP, length 392
19:49:18.581172 IP 10.70.20.194.fuscript > 10.70.120.248.8855: UDP, length 392
19:49:18.806412 IP 10.70.20.205.fuscript > 10.70.120.248.8855: UDP, length 436
For traffic from an Instant AP cluster, filter on the destination port that was configured on the Instant VC. TCP 8088 is used in the example command below.
[root@ale ~]# tcpdump port 8088
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
Check 7: Are the APs on the controller/IAP cluster able to hear client devices in their vicinity?
In this example, the output has been divided into multiple sections to better fit on the pages of this document. In the actual command-line interface, it will appear in a single, long table.
On the controller:
(pfe-controller) # show ap monitor client-list ap-name POC-ALE-03-81:92
Monitored Client Table
----------------------
mac bssid essid channel sta-type
--- ----- ----- ------- --------
60:f8:1d:b7:64:48 ac:a3:1e:55:89:72 hpn-byod 48 interfering
84:3a:4b:34:1d:5e 94:b4:0f:5c:a2:b0 App-Test-JI 36 interfering
5c:e0:c5:89:2b:f0 ac:a3:1e:55:6f:51 ethersphere-wpa2 48 interfering
c8:e0:eb:39:26:bf 18:64:72:e5:8e:90 pfe-psk 36 valid
60:02:b4:85:31:99 18:64:72:40:b9:d1 Angel-Media 36 interfering
e8:b1:fc:87:89:76 40:e3:d6:d7:6c:b0 Hd-lab-k12 36 interfering
5c:c5:d4:c1:17:9f 40:e3:d6:d7:6c:b0 Hd-lab-k12 36 interfering
auth phy-type dt/mt ut/it snr rssi cl-delay
---- -------- ----- ----- --- ---- --------
no 80211a-VHT-40 559/559 1/0 14 81 -
yes 80211a-HT-40 756/756 3/2 10 85 -
no 80211a-VHT-40 1385/1385 3/43 13 82 -
yes 80211a-VHT-80 1258/1258 11/10 18 77 -
yes 80211a-HT-40 82897/82897 9/8 16 79 -
yes 80211a-VHT-80 3054933/3054933 2/1 11 84 -
yes 80211a-VHT-80 3044573/3044573 3/2 9 86 -
<output snipped>
On the IAP:
AP2# sh ap monitor sta-list
Monitored Client Table
----------------------
mac bssid essid channel sta-type
--- ----- ----- ------- --------
ac:d1:b8:8a:6f:1f 40:e3:d6:d7:6c:b0 Hd-lab-k12 36 interfering
a4:5e:60:4a:4d:a3 94:b4:0f:5c:f7:50 IAP POC Lab 165 interfering
24:77:03:d5:ba:54 94:b4:0f:5c:f7:50 IAP POC Lab 165 interfering
a4:67:06:46:55:e7 94:b4:0f:5c:f7:50 IAP POC Lab 165 interfering
40:e2:30:1c:82:4b 40:e3:d6:d7:6c:b0 Hd-lab-k12 36 interfering
8c:29:37:e8:2d:70 94:b4:0f:5c:f7:50 IAP POC Lab 165 interfering
auth phy-type dt/mt ut/it snr rssi cl-delay
---- -------- ----- ----- --- ---- --------
yes 80211a 296962/136372 7/17 17 78 -
yes 80211a-VHT-20 15260/7148 4/2 24 71 -
yes 80211a-HT-20 387504/176661 8/3 18 77 -
yes 80211a-HT-20 4048/1902 437/203 15 80 -
yes 80211a 385484/176819 18/46898 19 76 -
no 80211a 1318/628 579/272 27 68 -
<output snipped>
If you have verified all the above steps and still do not see any location events on ALE, please open a Support ticket.

Problem: Very little -to- no locations are being generated for a specific client device.
Check 1: Check the RSSI feed to to see how many APs are contributing RSSI for the given client MAC. If no APs are reporting RSSI, then it might be an issue with ALE not being able to receive data from the WLAN (also see section WebSocket Client (ALE) for further troubleshooting).
If the source for RSSI is AMON:
[root@ale ~]# /opt/ale/bin/feed-reader -e tcp://localhost:7778 | grep 18:5e:0f:90:15:73 -A16
Attempting to 'connect' to endpoint: tcp://localhost:7778
Connected to endpoint: tcp://localhost:7778
Subscribed to topic: ""
If the source for RSSI is RTLS:
[root@ale ~]# /opt/ale/bin/feed-reader -e tcp://localhost:7777 | grep 18:5e:0f:90:15:73 -A16
Attempting to 'connect' to endpoint: tcp://localhost:7777
Connected to endpoint: tcp://localhost:7777
Subscribed to topic: ""
Check 3: If the RSSI feed shows any number of APs reporting the device MAC, look for what is happening to the device in the ale-location logs. If you can for a short while, turn up ale-location logs to TRACE level (if not TRACE, then at least DEBUG level). Then see what you can find out about this device by filtering on the MAC address of the device.
Figure 4 Trace Level
[root@ale ~]# tail -F /opt/ale/ale-location/logs/ale-location.log | grep 185e0f901573
2016-02-19 10:41:53.077 PST [pool-1-thread-2] DEBUG c.a.a.l.records.StationRecord - Station 185e0f901573 scheduled with 14 RSSIs:[RssiRecord [rssi=-40, tsSecs=1455907829, bssid=aca31e5a2750, channel=0], RssiRecord [rssi=-70, tsSecs=1455907819, bssid=aca31e59a0d0, channel=0], RssiRecord [rssi=-39, tsSecs=1455907823, bssid=aca31e5a2750, channel=0], RssiRecord [rssi=-83, tsSecs=1455907788, bssid=186472e18bf0, channel=0], RssiRecord [rssi=-58, tsSecs=1455907735, bssid=aca31e59a6f0, channel=0], RssiRecord [rssi=-58, tsSecs=1455907734, bssid=aca31e59a6f0, channel=0], RssiRecord [rssi=-66, tsSecs=1455907785, bssid=aca31e5a4c30, channel=0], RssiRecord [rssi=-84, tsSecs=1455907805, bssid=aca31e59c3f0, channel=0], RssiRecord [rssi=-72, tsSecs=1455907826, bssid=aca31e59a2b0, channel=0], RssiRecord [rssi=-60, tsSecs=1455907827, bssid=aca31e599cb0, channel=0], RssiRecord [rssi=-60, tsSecs=1455907807, bssid=aca31e599cb0, channel=0], RssiRecord [rssi=-71, tsSecs=1455907820, bssid=aca31e59a2b0, channel=0], RssiRecord [rssi=-86, tsSecs=1455907811, bssid=aca31e59a2d0, channel=0], RssiRecord [rssi=-86, tsSecs=1455907810, bssid=aca31e59a2d0, channel=0]]
2016-02-19 10:41:53.125 PST [engine-worker-4] DEBUG c.a.a.l.records.StationRecord - New location for station 185e0f901573: x=70.044075, y=81.055542, floor=7B27C59A75713E1F9D9B965F57497CA2, algo=ALGORITHM_ESTIMATION
2016-02-19 10:41:53.215 PST [pool-1-thread-2] TRACE c.a.a.l.handlers.BasicMatrixHandler - Station 185e0f901573 reported by unknown BSSID 6cf37febf690
2016-02-19 10:42:03.498 PST [pool-1-thread-2] DEBUG c.a.a.l.records.StationRecord - Station 185e0f901573 scheduled with 12 RSSIs:[RssiRecord [rssi=-70, tsSecs=1455907819, bssid=aca31e59a0d0, channel=0], RssiRecord [rssi=-39, tsSecs=1455907835, bssid=aca31e5a2750, channel=0], RssiRecord [rssi=-70, tsSecs=1455907835, bssid=aca31e59a0d0, channel=0], RssiRecord [rssi=-83, tsSecs=1455907838, bssid=186472e18bf0, channel=0], RssiRecord [rssi=-83, tsSecs=1455907788, bssid=186472e18bf0, channel=0], RssiRecord [rssi=-58, tsSecs=1455907735, bssid=aca31e59a6f0, channel=0], RssiRecord [rssi=-84, tsSecs=1455907805, bssid=aca31e59c3f0, channel=0], RssiRecord [rssi=-60, tsSecs=1455907827, bssid=aca31e599cb0, channel=0], RssiRecord [rssi=-66, tsSecs=1455907786, bssid=aca31e5a4c30, channel=0], RssiRecord [rssi=-72, tsSecs=1455907832, bssid=aca31e59a2b0, channel=0], RssiRecord [rssi=-72, tsSecs=1455907838, bssid=aca31e59a2b0, channel=0], RssiRecord [rssi=-86, tsSecs=1455907811, bssid=aca31e59a2d0, channel=0]]
2016-02-19 10:42:03.512 PST [pool-1-thread-2] TRACE c.a.a.l.handlers.BasicMatrixHandler - Station 185e0f901573 reported by unknown BSSID 6cf37febf690
2016-02-19 10:42:03.536 PST [engine-worker-5] DEBUG c.a.a.l.records.StationRecord - New location for station 185e0f901573: x=72.157089, y=74.203644, floor=7B27C59A75713E1F9D9B965F57497CA2, algo=ALGORITHM_ESTIMATION
2016-02-19 10:42:03.625 PST [pool-1-thread-2] TRACE c.a.a.l.handlers.BasicMatrixHandler - Station 185e0f901573 reported by unknown BSSID 6cf37febf690
In the example above, you can notice a couple of things:
1. | The client is being detected by a bunch of APs and its location (x,y) is also being computed by ALE. |
2. | The station is also being reported by an unknown BSSID (indicated by the third, fifth and seventh entries in the log). This means that ALE does not recognize the BSSID that is reporting the client device in question, possibly because the AP has not yet been identified in AirWave or placed on the VisualRF floor. Since ALE does not have any information on this particular AP, it discards any information reported by the AP. |

Problem: Cannot see as many location updates on ALE as there are associated devices on the WLAN.
There could be multiple reasons for this observation:
Client devices that are associated to the WLAN may not probe as frequently as other unassociated devices. To add to this behavior, for associated devices that are idle, there may not enough data frames that are being exchanged over the air. Due to these reasons, ALE may not receive enough client RSSIs to compute location. Adding AM density helps in the case of associated devices.
Ensure that NTP is configured on the controller/IAP as well as on ALE. A difference in timestamps between ALE and the WLAN may cause ALE to treat incoming data from the WLAN as stale and potentially discard it.
Your system might be running low in CPU/Memory and ALE cannot store any more locations in the internal DB.
If you are comparing locations shown in AirWave VisualRF with locations shown on the ALE map, keep in mind that the VisualRF map shows locations that have been historically recorded. The ALE map represents a recent snapshot and shows locations of devices as seen over the last few minutes. So if VisualRF shows a higher number of locations, it is possible that some of those are old ones.
In low AP-density networks, you can also consider switching to Context-only mode that gives you a proximity message rather than an actual location. It tells you that you are in the proximity of a particular AP.

Problem: Controller source on ALE is configured as RTLS. ALE is generating data for associated client devices but no data is observed for unassociated devices.
ALE does not generate presence/location data for unassociated devices.
ALE UI dashboard does not show unassociated devices.
Figure 5 No Data Observed for Unassociated Devices
ALE dashboard map does not show red dots (unassociated devices).
Figure 6 No Unassociated Devices
Check 1: Is the includeUnassocSta knob enabled on the controller?
Under Configuration > Select AP Group > Select AP System Profile > Advanced tab > RTLS Server Configuration:
Figure 7 includeUnassocSta Knob
Enable the includeUnassocSta knob and click on Apply.
Figure 8 Enable includeUnassocSta Knob
Verify the presence of unassociated devices on the ALE dashboard.
On the ALE UI > Monitoring:
Figure 9 Unassociated Devices Present
The same can be verified on the ALE Maps dashboard.
On the ALE UI > Monitoring > Map:
Figure 10 ALE Maps Dashboard
You can also check the output of the presence API to confirm you can see unassociated devices.
The value for the associated field will be false for unassociated devices.
[root@ale ~]# /opt/ale/bin/feed-reader -f presence
Attempting to 'connect' to endpoint: tcp://localhost:7779
Connected to endpoint: tcp://localhost:7779
Subscribed to topic: "presence"
[1] Recv event with topic "presence"
seq: 9288
timestamp: 1453927575
op: OP_ADD
topic_seq: 172
source_id: 005056852F31
presence {
sta_eth_mac {
addr: 34:68:95:ec:f0:db
}
associated: false
hashed_sta_eth_mac: 046AD455D891E4ED49E9FA2285383B6B8608EE6F
ap_name: POC-ALE-05-83:3c
radio_mac {
addr: 18:64:72:e8:33:d0
}
}
Check 2: Alternatively, consider using AMON as the data source on ALE instead of RTLS (recommended) and verify whether you can see events for unassociated client devices.
Figure 11 Enabling AMON

This section includes the following topics:

An error is seen when trying to connect ALE to AirWave.
Under Configuration > Mode > Add AirWave Server:
Figure 12 Adding AirWave
Figure 13 Error Fetching Sites from AirWave
Check 1: Are there any communication issues between ALE and AirWave?
Try performing a Telnet connection to the AirWave server on port 443 (the port that ALE uses to communicated with AirWave).
If you see this:
[root@ale ~]# telnet 10.70.120.251 443
Trying 10.70.120.251...
telnet: connect to address 10.70.120.251: No route to host
[root@ale ~]#
Or this:
[root@ale ~]# telnet 10.70.120.251 443
Trying 10.70.120.251...
telnet: connect to address 10.70.120.251: Connection refused
[root@ale ~]#
The above outputs indicate that ALE cannot communicate with AirWave either due to a routing issue, or there is a firewall on the network that is blocking connections to AirWave. Check for end-to-end network connectivity and also the firewall settings in your network to make sure AirWave is reachable.
You can also use a port scanning utility such as Nmap to further investigate firewall issues. Nmap is not installed on ALE by default.
Here's an example:
[root@ale ~]# nmap -p 22,443 10.70.120.251
Starting Nmap 5.51 ( http://nmap.org ) at 2016-01-28 21:07 UTC
Nmap scan report for 10.70.120.251
Host is up (0.00050s latency).
PORT STATE SERVICE
22/tcp open ssh
443/tcp open https
MAC Address: 00:50:56:85:7D:21 (VMware)
Nmap done: 1 IP address (1 host up) scanned in 0.51 seconds
[root@ale ~]#
Check 2: Is the VisualRF engine running on AirWave?
Figure 14 Enabling VisualRF Engine
Enable VisualRF. Under VisualRF > Setup > Enable VisualRF Engine > select Yes. Click on Save.
After a few minutes, try adding the AirWave IP on ALE: Under ALE Configuration > Mode > Add AirWave server IP > select floors.
Figure 15 Selecting AirWave Floors on ALE
The following output indicates that ALE was able to communicate with AirWave successfully.
Figure 16 ALE to AirWave Connection Successful

Problem: ALE shows clients being incorrectly placed on the floor map.
Figure 17 Dots Incorrectly Laid Out
Check 1: Are you running version 2.0.0.3 or newer? With ALE versions older than 2.0.0.3, there is an issue where configuring different metrics on ALE and AirWave results in clients being placed on the bottom and sides of the floor. The workaround was to use only "feet" metrics on AirWave and ALE but this issue is resolved in ALE 2.0.0.3.
[root@ale2 ~]# rpm -qa |grep ale
ale-persistence-2.0.0.2-53030.x86_64
ale-location-2.0.0.2-53030.x86_64
ale-utils-2.0.0.2-53030.x86_64
ale-monitconfig-2.0.0.2-53030.noarch
ale-jwebapp-2.0.0.2-53030.x86_64
ale-platform-2.0.0.2-53030.x86_64
ale-wstunnel-2.0.0.2-53030.x86_64
[root@ale2 ~]#
If you are running an older version of ALE, upgrade to 2.0.0.3 or newer:
[root@ale-2 ~]# sh ale-2.0.0.3-53845.run
The upgrade may take a few minutes to complete.
Check 2: Were the distance metrics recently changed on AirWave?
It is okay to have different metrics configured on AirWave and ALE, but if the metric unit was recently changed on AirWave, this may cause locations to be incorrectly computed on ALE, as shown above.
Under ALE Configuration > Options > General > Is the distance metric configured in FEET or METER?
Figure 18 ALE Distance Metric
Now check the distance metric configured on AirWave.
Under VisualRF > Setup > Use Metric Units:
Figure 19 Use Metric Units
In the above example, ALE is configured in FEET whereas AirWave is configured in METERS. If AirWave was recently configured to use different metric units from ALE, this is likely throwing off location calculation and causing clients to be wrongly displayed on the map.
Toggle the VisualRF engine.
Under VisualRF > Setup > Select Enable VisualRF Engine as No > Click on Save.
Figure 20 Set Enable VisualRF Engine to No
Now enable the VisualRF engine.
Under VisualRF > Setup > Select Enable VisualRF Engine as Yes > Click on Save.
Figure 21 Set Enable VisualRF Engine to Yes
It might take a few minutes for the VisualRF Engine to start, so you will not be able to access the VisualRF page during this time.
Re-add the AirWave entry on ALE.
Under ALE Configuration > Mode > Click on the delete icon > Add AirWave back > Select the same floor and complete the site-fetch process.
Figure 22 Delete AirWave Entry on ALE
Figure 23 Adding an AirWave Entry on ALE.
Figure 24 Specifying AirWave Credentials on ALE
Figure 25 Selecting Floors from AirWave
Figure 26 ALE to AirWave Connection Successful
Verify that the ALE map now displays client locations correctly.
Under ALE > Monitor > Map > Select the same floor.
Figure 27 ALE Map

Problem: How can I verify if the AP placement on AirWave is consistent with the APs that are sending RSSI feeds to ALE?
It is crucial to enure that APs are correctly placed in AirWave, because if ALE receives RSSI information from an AP that it hasn't learnt about from AirWave, the location engine will ignore these APs when computing client locations.
Look at the following logs to understand if this a problem in your deployment:
The following counters in the ale-location log (INFO level) indicate that ALE is receiving RSSI information from unknown BSSIDs:
2016-02-19 12:03:58.783 PST [metrics-logger-reporter-1-thread-1] INFO c.a.a.c.metrics.RegistryManager - type=COUNTER, name=com.aruba.ale.location.handlers.BasicMatrixHandler.rtls.bssidNotFound, count=0
2016-02-19 12:03:58.783 PST [metrics-logger-reporter-1-thread-1] INFO c.a.a.c.metrics.RegistryManager - type=COUNTER, name=com.aruba.ale.location.handlers.BasicMatrixHandler.vbr.bssidNotFound, count=810305
The above log indicates that there is a high incidence of AMON-based RSSI coming from APs that the location engine has not learned from AirWave.
When ale-location logs are set to TRACE level, the following log entry indicates this concern:
2016-02-19 10:42:03.625 PST [pool-1-thread-2] TRACE c.a.a.l.handlers.BasicMatrixHandler - Station 185e0f901573 reported by unknown BSSID 6cf37febf690
Corrective action would be to add this AP on AirWave, if not already present.

This section walks you through the process of configuring a WebSocket tunnel between ALE and analytics applications. Please use this section in conjunction with information on WebSocket tunnels documented in the ALE 2.1 User Guide.
In most deployments, ALE resides behind a firewall and the analytics applications that subscribe to the ALE feed may either be co-located with ALE or deployed in the cloud. If the application server is co-located, then it can subscribe to the ALE feed without the need of a WebSocket connection to ALE.
However, if the customer is using the services of a third-party analytics partner, then the analytics application in all likelihood will reside in the cloud. Because ALE is behind a firewall, the application cannot connect directly to ALE, hence the need of a secure WebSocket connection.
Once ALE initiates a WebSocket connection to the application, the application can now use the REST APIs or the Publish/Subscribe APIs to retrieve contextual data from ALE.
A WebSocket connection is secure since it uses HTTPS. Having a WebSocket connection can be especially beneficial in network environments that block non-web Internet connections.
Figure 28 WebSocket Connections
This section includes the following topics:

Please ensure that ALE can communicate with the analytics application (WebSocket server) on the port that the application is listening for WebSocket connection requests. By default, TCP 443 is used by the WebSocket software package. This port is configurable, as shown in step 4 of the section WebSocket Client (ALE).
|
ALE needs an Internet connection; it should be able to perform DNS resolution to be able to successfully establish WebSocket connections with cloud-based analytics applications. |

WebSocket Client (ALE)
Verify WebSocket Server Reachability
1. | On ALE, verify that you can resolve the CN of the server certificate, as ALE will use the CN to initiate the WebSocket connection. |
In the previous steps, CN=tme-websocket.arubanetworks.com was specified when creating the WebSocket server certificate. If this value is not publicly resolvable, then create an entry on ALE to locally resolve tme-websocket.arubanetworks.com.
[root@ale /]# vi /etc/hosts
127.0.0.1 localhost.localdomain localhost.localdomain localhost4 localhost4.localdomain4 localhost ale-2
::1 localhost.localdomain localhost.localdomain localhost6 localhost6.localdomain6 localhost ale-2
10.70.120.234 tme-websocket.arubanetworks.com <<<<---------Add
~
~
~
~
~
~
~
~
~
:wq <<<<<----- Save your config changes
Verify that you can ping the WebSocket server:
[root@ale /]# ping tme-websocket.arubanetworks.com
PING tme-websocket.arubanetworks.com (10.70.120.234) 56(84) bytes of data.
64 bytes from tme-websocket.arubanetworks.com (10.70.120.234): icmp_seq=1 ttl=64 time=0.526 ms
64 bytes from tme-websocket.arubanetworks.com (10.70.120.234): icmp_seq=2 ttl=64 time=0.345 ms
^C
--- tme-websocket.arubanetworks.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1267ms
rtt min/avg/max/mdev = 0.345/0.435/0.526/0.092 ms
[root@ale /]#
Trust the WebSocket Server's Identity
2. | The next step is to import the WebSocket server's chain of trust into ALE. In this example, the WebSocket server has a self-signed certificate that can be imported into ALE. |
There are a number of ways to pull the certificate from the WebSocket server, including Secure Copy (SCP), File Transfer Protocol (FTP), or manually copying the certificate. In the example below, we will attempt to pull the certificate directly from the WebSocket server using Openssl.
[root@ale ~]# echo -n | openssl s_client -connect tme-websocket.arubanetworks.com:4433 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /root/websocket-server.crt
depth=0 C = US, ST = CA, L = Sunnyvale, O = HPE Aruba, OU = TME, CN = tme-websocket.arubanetworks.com, emailAddress = tme@hpe.com
verify error:num=18:self signed certificate
verify return:1
depth=0 C = US, ST = CA, L = Sunnyvale, O = HPE Aruba, OU = TME, CN = tme-websocket.arubanetworks.com, emailAddress = tme@hpe.com
verify return:1
DONE
[root@ale ~]#
Verify that the server certificate was imported.
[root@ale ~]# ls
anaconda-ks.cfg install.log install.log.syslog websocket-server.crt
[root@ale ~]#
You can also issue the following command to verify that certificate contents can be read:
[root@ale ~]# openssl x509 -in websocket-server.crt -text
Now that the server certificate has been copied on ALE, import it into the trusted root certificate store on ALE.
[root@ale bin]# ./keytool -list -keystore ../jre/lib/security/cacerts -importcert -alias poclab-websocket-server-cert -file /root/websocket-server.crt
Enter keystore password: <<<<<------------ Type password "changeit"
Owner: EMAILADDRESS=tme@hpe.com, CN=tme-websocket.arubanetworks.com, OU=TME, O=HPE Aruba, L=Sunnyvale, ST=CA, C=US
Issuer: EMAILADDRESS=tme@hpe.com, CN=tme-websocket.arubanetworks.com, OU=TME, O=HPE Aruba, L=Sunnyvale, ST=CA, C=US
Serial number: a4ed1e24ccc80416
Valid from: Fri Jan 29 01:13:24 UTC 2016 until: Sat Jan 28 01:13:24 UTC 2017
Certificate fingerprints:
MD5: F2:F4:F1:07:40:1D:A7:9E:17:3F:3D:F7:C7:24:E3:A8
SHA1: 14:A5:64:9C:0D:A8:8A:4E:F5:17:DF:99:0A:2D:98:54
:3D:D2:83:39
SHA256: 91:8C:49:C1:81:AD:22:8B:0F:7A:13:8B:C3:1B:BA: A3:B5:CD:8E:A3:B3:AE:D8:76:C5:9B:F8:78:A4:2F:BC:D9
Signature algorithm name: SHA1withRSA
Version: 1
Trust this certificate? [no]: yes <<<<<------------ Type yes
Certificate was added to keystore
[root@ale bin]#
To verify the import was successful:
[root@ale bin]# ./keytool -list -keystore ../jre/lib/security/cacerts |grep poclab-websocket-server-cert -A1
Enter keystore password: changeit
poclab-websocket-server-cert, Jan 29, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): 14:A5:64:9C:0D:A8:8A:4E:F5:17:DF:99:0A:2D:98:54:3D:D2:83:39
[root@ale bin]#
Configure the WebSocket Entry On ALE
3. | On the ALE UI, specify the WebSocket server as the WebSocket end-point to connect to. |
Under Config > Options > WebSocket Tunnel > Remote End-Points > Click + to add the remote end-point.
Figure 30 Remote End-Point
Click Add. On the WebSocket Tunnel page, click Apply.
Verify the Connection
4. | You can view the “ale-wstunnel” log to verify on ALE that the connection was successfully established: |
[root@ale logs]# tailf /opt/ale/ale-wstunnel/logs/ale-wstunnel.log
The following output indicates a successful WebSocket connection:
2016-01-29 03:06:50.289 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.client.TunnelConnector - WebSocket connecting to wss://tme-websocket.arubanetworks.com:4433
2016-01-29 03:06:50.783 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.client.TunnelConnector - WebSocket connected to tme-websocket.arubanetworks.com:4433
Similarly, on the WebSocket server, you can monitor for incoming WebSocket connections from ALE:
[root@websocket-server logs]# tailf /opt/ale/ale-wstunnel/logs/ale-wstunnel.log
The following output indicates a successful WebSocket connection:
2016-01-29 02:01:01.858 UTC [vert.x-eventloop-thread-0] INFO com.aruba.ale.wstunnel.TunnelServer - Listening for clients on wss://0.0.0.0:4433
2016-01-29 02:01:01.867 UTC [vert.x-eventloop-thread-0] INFO com.aruba.ale.wstunnel.TunnelServer - Listening for web/API requests on http://localhost:8700
2016-01-29 03:06:50.724 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.s.WebSocketServerTunnel - Client '005056852F31' connected.
2016-01-29 03:06:50.730 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.s.WebSocketServerTunnel - - Mapping localhost:12000 -> localhost:8080
2016-01-29 03:06:50.731 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.s.WebSocketServerTunnel - - Mapping localhost:12001 -> localhost:7779
2016-01-29 03:06:50.731 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.s.WebSocketServerTunnel - - Mapping localhost:12002 -> localhost:443

Before testing the APIs on the WebSocket server, verify that ALE:WebSocket-server's {remote:local} port mappings are in place:
[root@websocket-server ~]# curl -v http://localhost:8700/clients
* About to connect() to localhost port 8700 (#0)
* Trying ::1... Connection refused
* Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8700 (#0)
> GET /clients HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: localhost:8700
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 339
<
* Connection #0 to host localhost left intact
* Closing connection #0
{"clients":[{"id":"005056852F31","uptime":57898177,"endpoints":[{"local_host":"localhost","local_port":12000,"remote_host":"localhost","remote_port":8080},{"local_host":"localhost","local_port":12001,"remote_host":"localhost","remote_port":7779},{"local_host":"localhost","local_port":12002,"remote_host":"localhost","remote_port":443}]}]}[root@websocket-server ~]#
The above output gives the following information:
The id field shows the ALE server that the WebSocket server is connected to, via the tunnel.
Remote port 8080 (used for REST APIs) is mapped to local port 12000.
Remote port 7779 (used for Pub/Sub APIs) is mapped to local port 12001.
Remote port 443 is mapped to local port 12002.
With ALE 2.0, all Polling API requests need to pass authentication. Just so we do not have to authenticate every time an API request is placed, let's store the credentials in a temporary cookie file.
curl -v -k --data "j_username=admin&j_password=welcome123" --cookie-jar /tmp/cook.txt http://localhost:12000/api/j_spring_security_check
Where admin/welcome123 are the ALE credentials.
Polling APIs
Now issue any of the Polling APIs. Below are a few examples.
Building API
[root@websocket-server ~]# curl -v -k --cookie /tmp/cook.txt http://localhost:12000/api/v1/building
* About to connect() to localhost port 12000 (#0)
* Trying ::1... connected
* Connected to localhost (::1) port 12000 (#0)
> GET /api/v1/building HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: localhost:12000
> Accept: */*
> Cookie: JSESSIONID=0DC5EB94A185EAD018F2E2C7FA8D97A8
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Content-Language: en-US
< Content-Length: 175
< Date: Fri, 29 Jan 2016 19:25:16 GMT
<
* Connection #0 to host localhost left intact
* Closing connection #0
{"Building_result": [{"msg": {"building_id": "659685E876A6325EB3F974FBBBA530F8","building_name": "POC lab","campus_id": "FCCD5881918E3C8D8628130773403AA6"},"ts": 1453948738}]}[root@websocket-server ~]#
Floor API
[root@websocket-server ~]# curl -v -k --cookie /tmp/cook.txt http://localhost:12000/api/v1/floor
* About to connect() to localhost port 12000 (#0)
* Trying ::1... connected
* Connected to localhost (::1) port 12000 (#0)
> GET /api/v1/floor HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: localhost:12000
> Accept: */*
> Cookie: JSESSIONID=0DC5EB94A185EAD018F2E2C7FA8D97A8
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Content-Language: en-US
< Content-Length: 407
< Date: Fri, 29 Jan 2016 19:24:08 GMT
<
* Connection #0 to host localhost left intact
* Closing connection #0
{"Floor_result": [{"msg": {"floor_id": "8B5207D8FDB1319AB35A72A32C7E5937","floor_name": "Floor 1","floor_latitude": 0.0,"floor_longitude": 0.0,"floor_img_path": "/download/10.70.120.251/images/7f67cc85-81c7-4e2d-9b95-0f385d0bc4c8.jpg","floor_img_width": 152.0,"floor_img_length": 147.0,"building_id": "659685E876A6325EB3F974FBBBA530F8","floor_level": 1.0,"units": "ft","grid_size": 10.0},"ts": 1453948738}]}[root@websocket-server ~]#
Station API
[root@websocket-server ~]# curl -v -k --cookie /tmp/cook.txt http://localhost:12000/api/v1/station
* About to connect() to localhost port 12000 (#0)
* Trying ::1... connected
* Connected to localhost (::1) port 12000 (#0)
> GET /api/v1/station HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: localhost:12000
> Accept: */*
> Cookie: JSESSIONID=0DC5EB94A185EAD018F2E2C7FA8D97A8
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Content-Language: en-US
< Content-Length: 1737
< Date: Fri, 29 Jan 2016 19:25:39 GMT
<
{"Station_result": [{"msg": {"sta_eth_mac": {"addr": "ACBC32B8599F"},"role": "authenticated","bssid": {"addr": "186472E81930"},"device_type": "OS X","hashed_sta_eth_mac": "D540B41E28ED584DE9753BB998D0755E126029B8","ap_name": "POC-ALE-03-81:92"},"ts": 1454080155},{"msg": {"sta_eth_mac": {"addr": "7831C1B8B3D8"},"role": "authenticated","bssid": {"addr": "186472E58E90"},"device_type": "OS X","sta_ip_address": {"af": "ADDR_FAMILY_INET","addr": "10.70.20.129"},"hashed_sta_eth_mac": "64D57D97954F40423B11B96DDE68412C5CDB50D1","hashed_sta_ip_address": "7256E2892D030E0FB796F20C30719A3DBBB0DBF0","ap_name": "POC-ALE-08-58:e8"},"ts": 1454090074},{"msg": {"sta_eth_mac": {"addr": "60F81DB76448"},"role": "authenticated","bssid": {"addr": "186472E8A810"},"device_type": "OS X","sta_ip_address": {"af": "ADDR_FAMILY_INET","addr": "10.70.20.227"},"hashed_sta_eth_mac": "FBD61BE219A039C83698488040552393D2CD49B9","hashed_sta_ip_address": "6BDE8191B71D6A72B7E6600B13CE1B933BE207DB","ap_name": "POC-ALE-07-8a:80"},"ts": 1454094479},{"m* Connection #0 to host localhost left intact
* Closing connection #0
sg": {"sta_eth_mac": {"addr": "247703D5B250"},"role": "authenticated","bssid": {"addr": "186472E7E9B0"},"sta_ip_address": {"af": "ADDR_FAMILY_INET","addr": "192.168.1.221"},"hashed_sta_eth_mac": "33F29AEA2CF514F153058AE2869A085B27517579","hashed_sta_ip_address": "183162954DC766404D096B4A7D4D9A79E3BA8B1F","ap_name": "POC-ALE-06-7e:9a"},"ts": 1454093728},{"msg": {"sta_eth_mac": {"addr": "0C3E9F5CEA01"},"role": "authenticated","bssid": {"addr": "186472E58E90"},"sta_ip_address": {"af": "ADDR_FAMILY_INET","addr": "10.70.20.217"},"hashed_sta_eth_mac": "7B35C0B8EF0F2050410AD5E5909A5EA0D5F17A61","hashed_sta_ip_address": "B84C592759DDA5A8CB05963E3C29B0A9EC8E068E","ap_name": "POC-ALE-08-58:e8"},"ts": 1454091368}]}[root@websocket-server ~]#
You can also test the Polling APIs via a Web browser.
Figure 31 WebSocket Authentication
Figure 32 WebSocket Floor API
In the above example, a Google Chrome extension called JSONView was used to make the JSON output more readable.
Publish/Subscribe APIs
To subscribe to the ALE feed in real-time, the customer can build a ZMQ-based app based on a language of their choice.
If you have an ALE instance as your WebSocket server, you can use a native debugging tool called feed-reader in order to test the feed. The feed-reader code (available in Java and C++) is available by contacting Support or your local Aruba account team, and can be used by customers and partners when building their own ZMQ-based apps.
Continuing the same example, local port 12001 corresponds to remote port 7779.
[root@websocket-server ~]# /opt/ale/bin/feed-reader -e tcp://localhost:12001
Attempting to 'connect' to endpoint: tcp://localhost:12001
Connected to endpoint: tcp://localhost:12001
Subscribed to topic: ""
[1] Recv event with topic "location/40:e2:30:1c:93:4d"
seq: 331807
timestamp: 1454097056
op: OP_UPDATE
topic_seq: 242538
source_id: 005056852F31
location {
sta_eth_mac {
addr: 40:e2:30:1c:93:4d
}
sta_location_x: 113.759
sta_location_y: 112.824
error_level: 24
associated: true
campus_id: FCCD5881918E3C8D8628130773403AA6
building_id: 659685E876A6325EB3F974FBBBA530F8
floor_id: 8B5207D8FDB1319AB35A72A32C7E5937
hashed_sta_eth_mac: 8A5C4F9F50A25B5B4E779DC27E562A1295FAD79B
geofence_ids: 09B034AE4CE93995AC92895E91C390FF
loc_algorithm: ALGORITHM_ESTIMATION
unit: FEET
}
[2] Recv event with topic "location/d0:e1:40:9f:02:52"
seq: 331808
timestamp: 1454097058
op: OP_UPDATE
topic_seq: 242539
source_id: 005056852F31
location {
sta_eth_mac {
addr: d0:e1:40:9f:02:52
}
sta_location_x: 27.247
sta_location_y: 41.2553
error_level: 30
associated: true
campus_id: FCCD5881918E3C8D8628130773403AA6
building_id: 659685E876A6325EB3F974FBBBA530F8
floor_id: 8B5207D8FDB1319AB35A72A32C7E5937
hashed_sta_eth_mac: D850DF23FF1B9A7B168AB80A32E2BECE76FA5E5B
loc_algorithm: ALGORITHM_ESTIMATION
unit: FEET
}
<output snipped>
You can subscribe to specific topics such as location, station, presence, etc.
[root@websocket-server ~]# /opt/ale/bin/feed-reader -e tcp://localhost:12001 -f station
Attempting to 'connect' to endpoint: tcp://localhost:12001
Connected to endpoint: tcp://localhost:12001
Subscribed to topic: "station"
[1] Recv event with topic "station"
seq: 332615
timestamp: 1454097231
op: OP_ADD
topic_seq: 223
source_id: 005056852F31
station {
sta_eth_mac {
addr: fc:c2:de:aa:94:bc
}
role: authenticated
bssid {
addr: 18:64:72:e5:8e:80
}
device_type: Android
hashed_sta_eth_mac: 49C6C19587FAEF786B53CD7CF46B3C7C110D2355
ap_name: POC-ALE-08-58:e8
}
<output snipped>

The WebSocket Server has the following connection issue:

Problem: ALE cannot establish the WebSocket connection.
This issue can be noticed:
From the ALE UI dashboard:
Figure 33 WebSocket Connection Failed
Via ALE logs:
[root@ale bin]# tailf /opt/ale/ale-wstunnel/logs/ale-wstunnel.log
2016-01-29 20:29:01.915 UTC [main] INFO com.aruba.ale.wstunnel.TunnelClient - Connecting with client ID of 005056852F31
2016-01-29 20:29:02.288 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.client.TunnelConnector - WebSocket connecting to wss://10.70.120.234:4433
2016-01-29 20:29:02.957 UTC [vert.x-eventloop-thread-0] ERROR c.a.a.w.client.TunnelConnector - WebSocket connection to 10.70.120.234:4433 failed. Will retry in 0 seconds...
2016-01-29 20:29:02.962 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.client.TunnelConnector - WebSocket connecting to wss://10.70.120.234:4433
2016-01-29 20:29:02.984 UTC [vert.x-eventloop-thread-0] ERROR c.a.a.w.client.TunnelConnector - WebSocket connection to 10.70.120.234:4433 failed. Will retry in 1 seconds...
2016-01-29 20:29:03.986 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.client.TunnelConnector - WebSocket connecting to wss://10.70.120.234:4433
Via the logs on the WebSocket server. The output of this log file will show no incoming connections from ALE.
[root@websocket-server ale-wstunnel]# tailf logs/ale-wstunnel.log
Check 1: Is this a WebSocket tunnel failing related issue? Add this command.
[# netstat -atnp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:2812 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:5120 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:7778 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:7779 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:3000 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:41878 127.0.0.1:5120 ESTABLISHED
tcp 0 0 127.0.0.1:7779 127.0.0.1:38250 ESTABLISHED
Check 2: Is the WebSocket server (FQDN) reachable via a ping test? If the server's FQDN is not resolvable on the network, add it manually on ALE.
[root@ale ~]# vi /etc/hosts
127.0.0.1 localhost.localdomain localhost.localdomain
localhost4 localhost4.localdomain4 localhost ale-2
1 localhost.localdomain localhost.localdomain localhost6 localhost6.localdomain6 localhost ale-2
10.70.120.234 tme-websocket.arubanetworks.com
~
~
~
~
~
-- INSERT -- <<<----- Type 'i' to edit. To save and quit, type Esc -> :wq -> Enter
Check 2: Is the WebSocket server listening for incoming ALE requests on TCP port 4433 (default port is TCP 443)?
You can also use a port scanning utility such as Nmap to further investigate firewall issues. Nmap is not installed on ALE by default.
[root@ale ~]# yum install nmap
Here's an example of Nmap usage:
[root@ale ~]# nmap -p 4433 tme-websocket.arubanetworks.com
Starting Nmap 5.51 ( http://nmap.org ) at 2016-01-30 00:18 UTC
Nmap scan report for tme-websocket.arubanetworks.com (10.70.120.234)
Host is up (0.00047s latency).
PORT STATE SERVICE
4433/tcp open unknown
MAC Address: 00:50:56:85:5D:0A (VMware)
Nmap done: 1 IP address (1 host up) scanned in 0.25 seconds
[root@ale ~]#
If the port state is filtered, there is a firewall on the network or on the WebSocket server that is blocking the connection requests.
If the port state is closed, there is no application on the other end that is listening on port 4433. Make sure you start the WebSocket service on the other end.
If the port state is open, there is an application that is listening on port 4433. This is the desired port state.
Check 3: Verify that the WebSocket server is running:
On the WebSocket server:
[root@websocket-server ale-wstunnel]# ps aux |grep Tunnel
root 5509 0.0 0.0 103244 868 pts/0 S+ 00:23 0:00 grep Tunnel
[root@websocket-server ale-wstunnel]#
The example output above shows that the WebSocket server hasn't been started yet.
To start the service:
[root@websocket-server ~]# /opt/ale/ale-wstunnel/bin/startup-server.sh
[root@websocket-server ~]#
Verify the service is running (indicated by com.aruba.ale.wstunnel.TunnelServer in the output below):
[root@websocket-server ~]# ps aux |grep Tunnel
root 5589 1.0 1.5 4065264 91344 ? Sl 00:25 0:02 /usr/java/jdk1.8.0_31/bin/java -cp /opt/ale/ale-wstunnel/conf:/opt/ale/ale-wstunnel/lib/ale-wstunnel-0.0.1.jar -Dlogger.basedir=/opt/ale/ale-wstunnel/logs -Djava.library.path=/opt/ale/lib64 -Dlogger.console=false com.aruba.ale.wstunnel.TunnelClient
root 5634 42.0 1.9 3982820 114080 pts/0 Sl 00:29 0:02 /usr/bin/java -cp /opt/ale/ale-wstunnel/conf:/opt/ale/ale-wstunnel/lib/ale-wstunnel-0.0.1.jar -Dlogger.basedir=/opt/ale/ale-wstunnel/logs -Dlogger.console=false com.aruba.ale.wstunnel.TunnelServer
root 5652 0.0 0.0 103244 872 pts/0 S+ 00:29 0:00 grep Tunnel
[root@websocket-server ~]#
Check 4: Ensure that the FQDN of the remote endpoint specified on ALE matches the Common Name (CN) on the server's certificate.
If the FQDN and CN do not match, then ALE cannot authenticate the WebSocket server and the connection will fail.
Check for the Websocket remote endpoint configured on ALE:
Figure 34 Remote Endpoint as FQDN on ALE
Use Openssl on ALE to verify the CN on the server certificate:
[root@ale ~]# openssl s_client -connect tme-websocket.arubanetworks.com:4433
CONNECTED(00000003)
depth=0 C = US, ST = CA, L = Sunnyvale, O = HPE Aruba, OU = TME, CN = tme-websocket.arubanetworks.com, emailAddress = tme@hpe.com
verify error:num=18:self signed certificate
verify return:1
depth=0 C = US, ST = CA, L = Sunnyvale, O = HPE Aruba, OU = TME, CN = tme-websocket.arubanetworks.com, emailAddress = tme@hpe.com
verify return:1
---
<output snipped>
Check 5: On ALE, is the remote endpoint configured as the WebSocket server's FQDN or the IP address?
It is recommended that the FQDN is specified as the remote endpoint on ALE and not the IP address. If the IP address is specified as the remote endpoint, the connection may fail. This means that the CN on the WebSocket server must also be configured to be the server's FQDN.
Example of a WebSocket remote endpoint incorrectly configured on ALE:
Figure 35 Remote Endpoint

This section includes the following topics:

There are five different logs that you can monitor in order to troubleshoot issues on ALE.
Platform logs (ale-platform): Use these logs to troubleshoot issues between the WLAN and ALE (for example, incoming data).
Location logs (ale-location): Use these logs troubleshoot issues related to location events, such as troubleshooting specific client devices, APs being ignored during location calculations, etc.
Persistence logs (ale-persistence): Use these logs to troubleshoot northbound API events being published by ALE.
Webapp logs (ale-jwebapp): Use these logs to troubleshoot communication issues between ALE and AirWave.
WebSocket logs (ale-wstunnel): Use these logs to troubleshoot WebSocket communication issues between ALE and external analytics applications.
All five logs are accessible from the /opt/ale/ file path on ALE.
[root@ale-2 ~]# cd /opt/ale/
[root@ale-2 ale]# ls
ale-jwebapp ale-location ale-persistence ale-platform ale-wstunnel bin include lib64 license naocloud noscan
[root@ale-2 ale]#
Below is an example command to monitor ale-location logs in real-time:
[root@ale-2 ale]# tailf /opt/ale/ale-location/logs/ale-location.log

There are five logging levels associated with each of these logs:
ERROR
WARNING
INFO (default for all logs)
DEBUG
TRACE
The TRACE logging level enables the most verbose logs, followed by DEBUG and INFO.
Depending on the issue you are troubleshooting, it is recommended to change the logging level on the corresponding logs to TRACE for maximum verbosity.
Figure 36 Enabling TRACE Level on ALE Logs

You can use the ale-wstunnel logs to troubleshoot issues with your WebSocket connection.
On the WebSocket Client (ALE)
On ALE, the logs are available in the following path:
/opt/ale/ale-wstunnel/logs/ale-wstunnel.log
Issue the following command to view the status of the WebSocket connection in real time:
[root@ale-2 ~]# tailf /opt/ale/ale-wstunnel/logs/ale-wstunnel.log
The following output indicates that a connection was initiated to the WebSocket server at the time indicated by the timestamp:
2016-03-10 21:59:00.884 UTC [main] INFO com.aruba.ale.wstunnel.TunnelClient - Connecting with client ID of 005056852F31
2016-03-10 21:59:02.143 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.client.TunnelConnector - WebSocket connecting to wss://tme-websocket.arubanetworks.com:4433
The following log indicates a successful WebSocket connection:
2016-03-10 21:59:02.321 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.client.TunnelConnector - WebSocket connected to tme-websocket.arubanetworks.com:4433
ALE will publish the status of established WebSocket connections every two minutes, indicated by the following output.
2016-03-10 22:01:00.878 UTC [metrics-logger-reporter-1-thread-1] INFO c.a.a.c.metrics.RegistryManager - type=GAUGE, name=com.aruba.ale.wstunnel.client.TunnelConnector.tme-websocket.arubanetworks.com, value=true
On the WebSocket Server
On the WebSocket server, the logs are available in the following path:
<file-path-where-websocket-package-was-installed>/ale-wstunnel-0.0.1/logs/ale-wstunnel.log
Issue the following command to view the status of the WebSocket connection in real time:
tailf <file-path>/ale-wstunnel-0.0.1/logs/ale-wstunnel.log
The following output indicates a successful WebSocket connection:
2016-03-10 21:59:02.280 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.s.WebSocketServerTunnel - Client '005056852F31' connected.
2016-03-10 21:59:02.280 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.s.WebSocketServerTunnel - - Mapping localhost:12000 -> localhost:8080
2016-03-10 21:59:02.280 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.s.WebSocketServerTunnel - - Mapping localhost:12001 -> localhost:7779
2016-03-10 21:59:02.281 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.s.WebSocketServerTunnel - - Mapping localhost:12002 -> localhost:443
Where 005056852F31 is the ID of the ALE server that initiated the WebSocket connection.

If you have exhausted all troubleshooting methods and the issue still persists, it may help to open a support ticket with HPE Aruba. Please remember to include the ALE Tech Support logs as part of the ticket.
They are available to download from the ALE UI under Maintenance > Download Tech Support Logs.
Figure 37 ALE Tech Support Logs

This section walks you through the process of configuring a WebSocket tunnel between ALE and analytics applications. Please use this section in conjunction with information on WebSocket tunnels documented in the ALE 2.0 User Guide.
In most deployments, ALE resides behind a firewall and the analytics applications that subscribe to the ALE feed may either be co-located with ALE or deployed in the cloud. If the application server is co-located, then it can subscribe to the ALE feed without the need of a WebSocket connection to ALE.
However, if the customer is using the services of a third-party analytics partner, then the analytics application in all likelihood will reside in the cloud. Because ALE is behind a firewall, the application cannot connect directly to ALE, hence the need of a secure WebSocket connection.
Once ALE initiates a WebSocket connection to the application, the application can now use the REST APIs or the Publish/Subscribe APIs to retrieve contextual data from ALE.
A WebSocket connection is secure since it uses HTTPS. Having a WebSocket connection can be especially beneficial in network environments that block non-web Internet connections.
Figure 38 WebSocket Connections
This section includes the following topics:

Please ensure that ALE can communicate with the analytics application (WebSocket server) on the port that the application is listening for WebSocket connection requests. By default, TCP 443 is used by the WebSocket software package. This port is configurable, as shown in step 4 of the section WebSocket Client (ALE).
|
ALE needs an Internet connection; it should be able to perform DNS resolution to be able to successfully establish WebSocket connections with cloud-based analytics applications. |

WebSocket Client (ALE)
Verify WebSocket Server Reachability
1. | On ALE, verify that you can resolve the CN of the server certificate, as ALE will use the CN to initiate the WebSocket connection. |
In the previous steps, CN=tme-websocket.arubanetworks.com was specified when creating the WebSocket server certificate. If this value is not publicly resolvable, then create an entry on ALE to locally resolve tme-websocket.arubanetworks.com.
[root@ale /]# vi /etc/hosts
127.0.0.1 localhost.localdomain localhost.localdomain localhost4 localhost4.localdomain4 localhost ale-2
::1 localhost.localdomain localhost.localdomain localhost6 localhost6.localdomain6 localhost ale-2
10.70.120.234 tme-websocket.arubanetworks.com <<<<---------Add
~
~
~
~
~
~
~
~
~
:wq <<<<<----- Save your config changes
Verify that you can ping the WebSocket server:
[root@ale /]# ping tme-websocket.arubanetworks.com
PING tme-websocket.arubanetworks.com (10.70.120.234) 56(84) bytes of data.
64 bytes from tme-websocket.arubanetworks.com (10.70.120.234): icmp_seq=1 ttl=64 time=0.526 ms
64 bytes from tme-websocket.arubanetworks.com (10.70.120.234): icmp_seq=2 ttl=64 time=0.345 ms
^C
--- tme-websocket.arubanetworks.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1267ms
rtt min/avg/max/mdev = 0.345/0.435/0.526/0.092 ms
[root@ale /]#
Trust the WebSocket Server's Identity
2. | The next step is to import the WebSocket server's chain of trust into ALE. In this example, the WebSocket server has a self-signed certificate that can be imported into ALE. |
There are a number of ways to pull the certificate from the WebSocket server, including Secure Copy (SCP), File Transfer Protocol (FTP), or manually copying the certificate. In the example below, we will attempt to pull the certificate directly from the WebSocket server using Openssl.
[root@ale ~]# echo -n | openssl s_client -connect tme-websocket.arubanetworks.com:4433 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /root/websocket-server.crt
depth=0 C = US, ST = CA, L = Sunnyvale, O = HPE Aruba, OU = TME, CN = tme-websocket.arubanetworks.com, emailAddress = tme@hpe.com
verify error:num=18:self signed certificate
verify return:1
depth=0 C = US, ST = CA, L = Sunnyvale, O = HPE Aruba, OU = TME, CN = tme-websocket.arubanetworks.com, emailAddress = tme@hpe.com
verify return:1
DONE
[root@ale ~]#
Verify that the server certificate was imported.
[root@ale ~]# ls
anaconda-ks.cfg install.log install.log.syslog websocket-server.crt
[root@ale ~]#
You can also issue the following command to verify that certificate contents can be read:
[root@ale ~]# openssl x509 -in websocket-server.crt -text
Now that the server certificate has been copied on ALE, import it into the trusted root certificate store on ALE.
[root@ale bin]# ./keytool -list -keystore ../jre/lib/security/cacerts -importcert -alias poclab-websocket-server-cert -file /root/websocket-server.crt
Enter keystore password: <<<<<------------ Type password "changeit"
Owner: EMAILADDRESS=tme@hpe.com, CN=tme-websocket.arubanetworks.com, OU=TME, O=HPE Aruba, L=Sunnyvale, ST=CA, C=US
Issuer: EMAILADDRESS=tme@hpe.com, CN=tme-websocket.arubanetworks.com, OU=TME, O=HPE Aruba, L=Sunnyvale, ST=CA, C=US
Serial number: a4ed1e24ccc80416
Valid from: Fri Jan 29 01:13:24 UTC 2016 until: Sat Jan 28 01:13:24 UTC 2017
Certificate fingerprints:
MD5: F2:F4:F1:07:40:1D:A7:9E:17:3F:3D:F7:C7:24:E3:A8
SHA1: 14:A5:64:9C:0D:A8:8A:4E:F5:17:DF:99:0A:2D:98:54
:3D:D2:83:39
SHA256: 91:8C:49:C1:81:AD:22:8B:0F:7A:13:8B:C3:1B:BA: A3:B5:CD:8E:A3:B3:AE:D8:76:C5:9B:F8:78:A4:2F:BC:D9
Signature algorithm name: SHA1withRSA
Version: 1
Trust this certificate? [no]: yes <<<<<------------ Type yes
Certificate was added to keystore
[root@ale bin]#
To verify the import was successful:
[root@ale bin]# ./keytool -list -keystore ../jre/lib/security/cacerts |grep poclab-websocket-server-cert -A1
Enter keystore password: changeit
poclab-websocket-server-cert, Jan 29, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): 14:A5:64:9C:0D:A8:8A:4E:F5:17:DF:99:0A:2D:98:54:3D:D2:83:39
[root@ale bin]#
Configure the WebSocket Entry On ALE
3. | On the ALE UI, specify the WebSocket server as the WebSocket end-point to connect to. |
Under Config > Options > WebSocket Tunnel > Remote End-Points > Click + to add the remote end-point.
Figure 40 Remote End-Point
Click Add. On the WebSocket Tunnel page, click Apply.
Verify the Connection
4. | You can view the “ale-wstunnel” log to verify on ALE that the connection was successfully established: |
[root@ale logs]# tailf /opt/ale/ale-wstunnel/logs/ale-wstunnel.log
The following output indicates a successful WebSocket connection:
2016-01-29 03:06:50.289 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.client.TunnelConnector - WebSocket connecting to wss://tme-websocket.arubanetworks.com:4433
2016-01-29 03:06:50.783 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.client.TunnelConnector - WebSocket connected to tme-websocket.arubanetworks.com:4433
Similarly, on the WebSocket server, you can monitor for incoming WebSocket connections from ALE:
[root@websocket-server logs]# tailf /opt/ale/ale-wstunnel/logs/ale-wstunnel.log
The following output indicates a successful WebSocket connection:
2016-01-29 02:01:01.858 UTC [vert.x-eventloop-thread-0] INFO com.aruba.ale.wstunnel.TunnelServer - Listening for clients on wss://0.0.0.0:4433
2016-01-29 02:01:01.867 UTC [vert.x-eventloop-thread-0] INFO com.aruba.ale.wstunnel.TunnelServer - Listening for web/API requests on http://localhost:8700
2016-01-29 03:06:50.724 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.s.WebSocketServerTunnel - Client '005056852F31' connected.
2016-01-29 03:06:50.730 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.s.WebSocketServerTunnel - - Mapping localhost:12000 -> localhost:8080
2016-01-29 03:06:50.731 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.s.WebSocketServerTunnel - - Mapping localhost:12001 -> localhost:7779
2016-01-29 03:06:50.731 UTC [vert.x-eventloop-thread-0] INFO c.a.a.w.s.WebSocketServerTunnel - - Mapping localhost:12002 -> localhost:443

Before testing the APIs on the WebSocket server, verify that ALE:WebSocket-server's {remote:local} port mappings are in place:
[root@websocket-server ~]# curl -v http://localhost:8700/clients
* About to connect() to localhost port 8700 (#0)
* Trying ::1... Connection refused
* Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8700 (#0)
> GET /clients HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: localhost:8700
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 339
<
* Connection #0 to host localhost left intact
* Closing connection #0
{"clients":[{"id":"005056852F31","uptime":57898177,"endpoints":[{"local_host":"localhost","local_port":12000,"remote_host":"localhost","remote_port":8080},{"local_host":"localhost","local_port":12001,"remote_host":"localhost","remote_port":7779},{"local_host":"localhost","local_port":12002,"remote_host":"localhost","remote_port":443}]}]}[root@websocket-server ~]#
The above output gives the following information:
The id field shows the ALE server that the WebSocket server is connected to, via the tunnel.
Remote port 8080 (used for REST APIs) is mapped to local port 12000.
Remote port 7779 (used for Pub/Sub APIs) is mapped to local port 12001.
Remote port 443 is mapped to local port 12002.
With ALE 2.0, all Polling API requests need to pass authentication. Just so we do not have to authenticate every time an API request is placed, let's store the credentials in a temporary cookie file.
curl -v -k --data "j_username=admin&j_password=welcome123" --cookie-jar /tmp/cook.txt http://localhost:12000/api/j_spring_security_check
Where admin/welcome123 are the ALE credentials.
Polling APIs
Now issue any of the Polling APIs. Below are a few examples.
Building API
[root@websocket-server ~]# curl -v -k --cookie /tmp/cook.txt http://localhost:12000/api/v1/building
* About to connect() to localhost port 12000 (#0)
* Trying ::1... connected
* Connected to localhost (::1) port 12000 (#0)
> GET /api/v1/building HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: localhost:12000
> Accept: */*
> Cookie: JSESSIONID=0DC5EB94A185EAD018F2E2C7FA8D97A8
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Content-Language: en-US
< Content-Length: 175
< Date: Fri, 29 Jan 2016 19:25:16 GMT
<
* Connection #0 to host localhost left intact
* Closing connection #0
{"Building_result": [{"msg": {"building_id": "659685E876A6325EB3F974FBBBA530F8","building_name": "POC lab","campus_id": "FCCD5881918E3C8D8628130773403AA6"},"ts": 1453948738}]}[root@websocket-server ~]#
Floor API
[root@websocket-server ~]# curl -v -k --cookie /tmp/cook.txt http://localhost:12000/api/v1/floor
* About to connect() to localhost port 12000 (#0)
* Trying ::1... connected
* Connected to localhost (::1) port 12000 (#0)
> GET /api/v1/floor HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: localhost:12000
> Accept: */*
> Cookie: JSESSIONID=0DC5EB94A185EAD018F2E2C7FA8D97A8
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Content-Language: en-US
< Content-Length: 407
< Date: Fri, 29 Jan 2016 19:24:08 GMT
<
* Connection #0 to host localhost left intact
* Closing connection #0
{"Floor_result": [{"msg": {"floor_id": "8B5207D8FDB1319AB35A72A32C7E5937","floor_name": "Floor 1","floor_latitude": 0.0,"floor_longitude": 0.0,"floor_img_path": "/download/10.70.120.251/images/7f67cc85-81c7-4e2d-9b95-0f385d0bc4c8.jpg","floor_img_width": 152.0,"floor_img_length": 147.0,"building_id": "659685E876A6325EB3F974FBBBA530F8","floor_level": 1.0,"units": "ft","grid_size": 10.0},"ts": 1453948738}]}[root@websocket-server ~]#
Station API
[root@websocket-server ~]# curl -v -k --cookie /tmp/cook.txt http://localhost:12000/api/v1/station
* About to connect() to localhost port 12000 (#0)
* Trying ::1... connected
* Connected to localhost (::1) port 12000 (#0)
> GET /api/v1/station HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: localhost:12000
> Accept: */*
> Cookie: JSESSIONID=0DC5EB94A185EAD018F2E2C7FA8D97A8
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Content-Language: en-US
< Content-Length: 1737
< Date: Fri, 29 Jan 2016 19:25:39 GMT
<
{"Station_result": [{"msg": {"sta_eth_mac": {"addr": "ACBC32B8599F"},"role": "authenticated","bssid": {"addr": "186472E81930"},"device_type": "OS X","hashed_sta_eth_mac": "D540B41E28ED584DE9753BB998D0755E126029B8","ap_name": "POC-ALE-03-81:92"},"ts": 1454080155},{"msg": {"sta_eth_mac": {"addr": "7831C1B8B3D8"},"role": "authenticated","bssid": {"addr": "186472E58E90"},"device_type": "OS X","sta_ip_address": {"af": "ADDR_FAMILY_INET","addr": "10.70.20.129"},"hashed_sta_eth_mac": "64D57D97954F40423B11B96DDE68412C5CDB50D1","hashed_sta_ip_address": "7256E2892D030E0FB796F20C30719A3DBBB0DBF0","ap_name": "POC-ALE-08-58:e8"},"ts": 1454090074},{"msg": {"sta_eth_mac": {"addr": "60F81DB76448"},"role": "authenticated","bssid": {"addr": "186472E8A810"},"device_type": "OS X","sta_ip_address": {"af": "ADDR_FAMILY_INET","addr": "10.70.20.227"},"hashed_sta_eth_mac": "FBD61BE219A039C83698488040552393D2CD49B9","hashed_sta_ip_address": "6BDE8191B71D6A72B7E6600B13CE1B933BE207DB","ap_name": "POC-ALE-07-8a:80"},"ts": 1454094479},{"m* Connection #0 to host localhost left intact
* Closing connection #0
sg": {"sta_eth_mac": {"addr": "247703D5B250"},"role": "authenticated","bssid": {"addr": "186472E7E9B0"},"sta_ip_address": {"af": "ADDR_FAMILY_INET","addr": "192.168.1.221"},"hashed_sta_eth_mac": "33F29AEA2CF514F153058AE2869A085B27517579","hashed_sta_ip_address": "183162954DC766404D096B4A7D4D9A79E3BA8B1F","ap_name": "POC-ALE-06-7e:9a"},"ts": 1454093728},{"msg": {"sta_eth_mac": {"addr": "0C3E9F5CEA01"},"role": "authenticated","bssid": {"addr": "186472E58E90"},"sta_ip_address": {"af": "ADDR_FAMILY_INET","addr": "10.70.20.217"},"hashed_sta_eth_mac": "7B35C0B8EF0F2050410AD5E5909A5EA0D5F17A61","hashed_sta_ip_address": "B84C592759DDA5A8CB05963E3C29B0A9EC8E068E","ap_name": "POC-ALE-08-58:e8"},"ts": 1454091368}]}[root@websocket-server ~]#
You can also test the Polling APIs via a Web browser.
Figure 41 WebSocket Authentication
Figure 42 WebSocket Floor API
In the above example, a Google Chrome extension called JSONView was used to make the JSON output more readable.
Publish/Subscribe APIs
To subscribe to the ALE feed in real-time, the customer can build a ZMQ-based app based on a language of their choice.
If you have an ALE instance as your WebSocket server, you can use a native debugging tool called feed-reader in order to test the feed. The feed-reader code (available in Java and C++) is available by contacting Support or your local Aruba account team, and can be used by customers and partners when building their own ZMQ-based apps.
Continuing the same example, local port 12001 corresponds to remote port 7779.
[root@websocket-server ~]# /opt/ale/bin/feed-reader -e tcp://localhost:12001
Attempting to 'connect' to endpoint: tcp://localhost:12001
Connected to endpoint: tcp://localhost:12001
Subscribed to topic: ""
[1] Recv event with topic "location/40:e2:30:1c:93:4d"
seq: 331807
timestamp: 1454097056
op: OP_UPDATE
topic_seq: 242538
source_id: 005056852F31
location {
sta_eth_mac {
addr: 40:e2:30:1c:93:4d
}
sta_location_x: 113.759
sta_location_y: 112.824
error_level: 24
associated: true
campus_id: FCCD5881918E3C8D8628130773403AA6
building_id: 659685E876A6325EB3F974FBBBA530F8
floor_id: 8B5207D8FDB1319AB35A72A32C7E5937
hashed_sta_eth_mac: 8A5C4F9F50A25B5B4E779DC27E562A1295FAD79B
geofence_ids: 09B034AE4CE93995AC92895E91C390FF
loc_algorithm: ALGORITHM_ESTIMATION
unit: FEET
}
[2] Recv event with topic "location/d0:e1:40:9f:02:52"
seq: 331808
timestamp: 1454097058
op: OP_UPDATE
topic_seq: 242539
source_id: 005056852F31
location {
sta_eth_mac {
addr: d0:e1:40:9f:02:52
}
sta_location_x: 27.247
sta_location_y: 41.2553
error_level: 30
associated: true
campus_id: FCCD5881918E3C8D8628130773403AA6
building_id: 659685E876A6325EB3F974FBBBA530F8
floor_id: 8B5207D8FDB1319AB35A72A32C7E5937
hashed_sta_eth_mac: D850DF23FF1B9A7B168AB80A32E2BECE76FA5E5B
loc_algorithm: ALGORITHM_ESTIMATION
unit: FEET
}
<output snipped>
You can subscribe to specific topics such as location, station, presence, etc.
[root@websocket-server ~]# /opt/ale/bin/feed-reader -e tcp://localhost:12001 -f station
Attempting to 'connect' to endpoint: tcp://localhost:12001
Connected to endpoint: tcp://localhost:12001
Subscribed to topic: "station"
[1] Recv event with topic "station"
seq: 332615
timestamp: 1454097231
op: OP_ADD
topic_seq: 223
source_id: 005056852F31
station {
sta_eth_mac {
addr: fc:c2:de:aa:94:bc
}
role: authenticated
bssid {
addr: 18:64:72:e5:8e:80
}
device_type: Android
hashed_sta_eth_mac: 49C6C19587FAEF786B53CD7CF46B3C7C110D2355
ap_name: POC-ALE-08-58:e8
}
<output snipped>
Was this information helpful?
Great! Thanks for the feedback.