|
|
@@ -0,0 +1,257 @@ |
|
|
// Libraries |
|
|
#include <Bridge.h> |
|
|
#include <YunClient.h> |
|
|
|
|
|
// Defines |
|
|
#define NEOPIXEL_PIN 8 |
|
|
|
|
|
// Constants for STOMP |
|
|
const int DISCONNECTED = 0; |
|
|
const int CONNECTING = 1; |
|
|
const int CONNECTED = 2; |
|
|
const int WAITING = 3; |
|
|
const int SUBSCRIBING = 4; |
|
|
const int SUBSCRIBED = 5; |
|
|
const int SENDING = 6; |
|
|
const int SENT = 7; |
|
|
|
|
|
// Constants for application |
|
|
const int PORT = 61613; |
|
|
const String ENDPOINT = "kaazing.kevinhoyt.com"; |
|
|
const String TOPIC = "/topic/heart"; |
|
|
|
|
|
// Global |
|
|
int counter; |
|
|
int state; |
|
|
String session; |
|
|
YunClient client; |
|
|
|
|
|
// Setup |
|
|
void setup() |
|
|
{ |
|
|
// Initially disconnected |
|
|
state = DISCONNECTED; |
|
|
|
|
|
// Serial for debugging |
|
|
Serial.begin( 9600 ); |
|
|
|
|
|
// Start Yun bridge |
|
|
// Used for network connectivity |
|
|
Bridge.begin(); |
|
|
|
|
|
// Wait until bridge is open |
|
|
while( !Serial ); |
|
|
} |
|
|
|
|
|
// Loop |
|
|
void loop() |
|
|
{ |
|
|
int start; |
|
|
String body; |
|
|
String frame; |
|
|
String response; |
|
|
|
|
|
// If disconnected |
|
|
if( state == DISCONNECTED ) |
|
|
{ |
|
|
// Connect to server |
|
|
if( client.connect( "kaazing.kevinhoyt.com", 61613 ) ) |
|
|
{ |
|
|
// Set connecting state |
|
|
state = CONNECTING; |
|
|
Serial.println( "Connecting..." ); |
|
|
} else { |
|
|
// Problem connecting |
|
|
Serial.println( "Not connected" ); |
|
|
} |
|
|
// Connected to server |
|
|
} else if( state == CONNECTING ) { |
|
|
// Initiate STOMP connection |
|
|
client.println( "CONNECT" ); |
|
|
client.println( "accept-version:1.2" ); |
|
|
client.print( "host:" ); |
|
|
client.println( "kaazing.kevinhoyt.com" ); |
|
|
client.println(); |
|
|
client.write( 0x0 ); |
|
|
|
|
|
// Waiting for response |
|
|
Serial.println( "Connect header sent..." ); |
|
|
state = WAITING; |
|
|
// Connected to STOMP broker |
|
|
} else if( state == CONNECTED ) { |
|
|
// Subscribe to specified destination |
|
|
client.println( "SUBSCRIBE" ); |
|
|
client.print( "id:" ); |
|
|
client.println( session ); |
|
|
client.print( "destination:" ); |
|
|
client.println( TOPIC ); |
|
|
client.println( "receipt:subscribed" ); |
|
|
client.println(); |
|
|
client.write( 0x0 ); |
|
|
|
|
|
// Subscribing to topic |
|
|
Serial.println( "Subscribing to topic..." ); |
|
|
state = SUBSCRIBING; |
|
|
} else if( state == SUBSCRIBED ) { |
|
|
counter = counter + 1; |
|
|
body = String( counter ); |
|
|
|
|
|
client.println( "SEND" ); |
|
|
client.print( "destination:" ); |
|
|
client.println( TOPIC ); |
|
|
client.println( "content-type:text/plain" ); |
|
|
// client.print( "content-length:" ); |
|
|
// client.println( body.length() ); |
|
|
client.print( "receipt:message-" ); |
|
|
client.println( counter ); |
|
|
client.println(); |
|
|
client.println( body ); |
|
|
client.write( 0x0 ); |
|
|
|
|
|
state = SENDING; |
|
|
Serial.println( "Sending message..." ); |
|
|
} |
|
|
|
|
|
// Incoming data from broker |
|
|
if( client.available() > 0 ) |
|
|
{ |
|
|
response = client.readStringUntil( 0x0 ); |
|
|
|
|
|
/* |
|
|
Serial.print( "*** Response Start (" ); |
|
|
Serial.print( response.length() ); |
|
|
Serial.println( ") ***" ); |
|
|
Serial.println( response ); |
|
|
Serial.println( "*** Response End ***" ); |
|
|
*/ |
|
|
|
|
|
if( response.length() > 0 ) |
|
|
{ |
|
|
frame = getValue( response, 0, "\n" ); |
|
|
|
|
|
if( frame == "CONNECTED" ) |
|
|
{ |
|
|
// Get session for later reference |
|
|
session = getHeader( response, "session" ); |
|
|
Serial.print( "Session: " ); |
|
|
Serial.println( session ); |
|
|
|
|
|
// Set state |
|
|
state = CONNECTED; |
|
|
Serial.println( "Connected." ); |
|
|
} else if( frame == "MESSAGE" ) { |
|
|
body = getValue( response, 1, "\n\n" ); |
|
|
|
|
|
Serial.print( "Message: " ); |
|
|
Serial.println( body ); |
|
|
} else if( frame == "RECEIPT" ) { |
|
|
if( state == SUBSCRIBING ) |
|
|
{ |
|
|
state = SUBSCRIBED; |
|
|
Serial.println( "Subscribed." ); |
|
|
} else if( state == SENDING ) { |
|
|
state = SUBSCRIBED; |
|
|
Serial.println( "Sent." ); |
|
|
|
|
|
delay( 1000 ); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
// Read last null byte |
|
|
client.read(); |
|
|
} |
|
|
} |
|
|
|
|
|
// Count the number of parts in a string |
|
|
// Used to help replace lack of split |
|
|
int count( String content, String delimeter ) |
|
|
{ |
|
|
int count = 0; |
|
|
int end; |
|
|
int start = 0; |
|
|
|
|
|
// Count occurances of delimeter |
|
|
do { |
|
|
end = content.indexOf( delimeter, start ); |
|
|
start = end + 1; |
|
|
count = count + 1; |
|
|
} while( end > 0 ); |
|
|
|
|
|
// Return occurance count |
|
|
return count; |
|
|
} |
|
|
|
|
|
// Reads response for specific header |
|
|
// Extracts and returns header value |
|
|
String getHeader( String content, String header ) |
|
|
{ |
|
|
int parts; |
|
|
int start; |
|
|
String line; |
|
|
String prefix; |
|
|
String result; |
|
|
|
|
|
// How many lines in response |
|
|
parts = count( content, "\n" ); |
|
|
|
|
|
// Start on line after frame line |
|
|
// Look for header prefix match |
|
|
for( int p = 1; p < parts; p++ ) |
|
|
{ |
|
|
// Header line |
|
|
// Split into parts |
|
|
line = getValue( content, p, "\n" ); |
|
|
prefix = getValue( line, 0, ":" ); |
|
|
|
|
|
// If prefix matches |
|
|
if( prefix == header ) |
|
|
{ |
|
|
// Get value for header |
|
|
start = line.indexOf( ":" ) + 1; |
|
|
result = line.substring( start ); |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
// Return result |
|
|
return result; |
|
|
} |
|
|
|
|
|
// Get a specific section of a string |
|
|
// Based on delimeters |
|
|
// Used to replace lack of split |
|
|
String getValue( String content, int part, String delimeter ) |
|
|
{ |
|
|
int end; |
|
|
int start = 0; |
|
|
String result; |
|
|
|
|
|
// Iterate past unwanted values |
|
|
for( int count = 0; count < part; count++ ) |
|
|
{ |
|
|
end = content.indexOf( delimeter, start ); |
|
|
start = end + delimeter.length(); |
|
|
} |
|
|
|
|
|
// Get next occurance of delimeter |
|
|
// May return -1 if not found |
|
|
end = content.indexOf( delimeter, start ); |
|
|
|
|
|
// If no more occurances |
|
|
if( end == -1 ) |
|
|
{ |
|
|
// Must be last value in content |
|
|
// Parse out remainder |
|
|
result = content.substring( start ); |
|
|
} else { |
|
|
// Otherwise parse out segment of content |
|
|
result = content.substring( start, end ); |
|
|
} |
|
|
|
|
|
// Clean off white space |
|
|
result.trim(); |
|
|
|
|
|
// Return resulting content |
|
|
return result; |
|
|
} |