How could I use a hostname instead of an i.p. to point to my pc in this example?

Hi,
ive successflly compiled trublions port of the cnmat OSCuino library, and would very much like it to lookup my dyndns hostname instead of it needing my pc’s i.p everytime.

heres the code where i would normally enter my i.p:
//----- IP ADRESSES
IPAddress computerIPAddress = IPAddress(193,90,167,89); // put the IP address of your computer here
IPAddress coreIPAddress;
OSCMessage coreIPMessage("/coreip");

would it be possible to somehow have the core lookup my dyddns account for this i.p?

Here is a way:

uint32_t ip_addr = 0; //TI CC3000 IP addresses are uint32 in reverse order
char host[] = "www.myhost.com";

if(gethostbyname(host, strlen(host), &ip_addr) > 0)   {
  IPAddress remote_addr(BYTE_N(ip_addr, 3), BYTE_N(ip_addr, 2), BYTE_N(ip_addr, 1), BYTE_N(ip_addr, 0));
} else {
//report error didn't find it
}

I have been meaning to wrap this up with a bow and put in a pull request but there are some funny cases since you can’t run this until the network is up

2 Likes

thanks so much for sharing! I’m struggling to compile this into my application.cpp,
would you mind showing me where to include this?

heres my application.cpp code:

#include "application.h"
#include "OSC/OSCMessage.h"
#include "OSC/OSCBundle.h"

//----- OUTPUTS
int led1 = D0;
int led2 = D1;


//----- REGISTERED OSC COMMANDS
char OscCmd_led[5] = "/led";							// 4 characters  + 1 for the "null-terminated string" -> '\0'
char OscCmd_TestSendMsg[13] = "/sendTestMsg";			// 12 characters + 1 for the "null-terminated string" -> '\0'
char OscCmd_TestSendBndl[14] = "/sendTestBndl";			// 13 characters + 1 for the "null-terminated string" -> '\0'
char OscCmd_SwitchToMessages[16] = "/manageMessages";	// 15 characters + 1 for the "null-terminated string" -> '\0'
char OscCmd_SwtichToBundles[15] = "/manageBundles";		// 14 characters + 1 for the "null-terminated string" -> '\0'


//----- IP ADRESSES
IPAddress computerIPAddress = IPAddress(193,90,167,89);	// put the IP address of your computer here
IPAddress coreIPAddress;
OSCMessage coreIPMessage("/coreip");


//----- PORTS
#define LOCALPORT  8888		// to send data to the Spark Core (from the computer)
#define REMOTEPORT 9999		// to send data to the computer (from here)


//----- MANAGING OSC MESSAGES OR OSC BUNDLES
int manageMessages = 0;
int manageBundles = 0;


//----- UDP + overloading the inappropriate UDP functions of the Spark Core (REQUIRED !)
class myUDP : public UDP {
private :
	uint8_t myBuffer[512];
	int offset = 0;
public :
	virtual int beginPacket(IPAddress ip, uint16_t port){
		offset = 0;
		return UDP::beginPacket(ip, port);
	};
	virtual int endPacket(){
		return UDP::write(myBuffer, offset);
	};
	virtual size_t write(uint8_t buffer) {
		write(&buffer, 1);
		return 1;
	}
	virtual size_t write(const uint8_t *buffer, size_t size) {
		memcpy(&myBuffer[offset], buffer, size);
		offset += size;
		return size;
	}
};

myUDP Udp;


//=========================================================================================
//=========================================================================================
void setup()
{
	// Initialize D0 + D1 pins as output for the two LEDs
	pinMode(led1, OUTPUT);
	pinMode(led2, OUTPUT);

	// Start UDP
	Udp.begin(LOCALPORT);

	// Get the IP address of the Spark Core and send it as an OSC Message
	coreIPAddress = Network.localIP();
	coreIPMessage.add(coreIPAddress[0]).add(coreIPAddress[1]).add(coreIPAddress[2]).add(coreIPAddress[3]);

	Udp.beginPacket(computerIPAddress, REMOTEPORT);
	coreIPMessage.send(Udp);
	Udp.endPacket();

	// First manage OSCMessages and not OSCBundles
	manageMessages = 1;
}


//=========================================================================================
//===== TEST receiving a request to take OSC Bundles into account
//=========================================================================================
void switchToBundles(OSCMessage &mess) { manageMessages = 0; manageBundles = 1;}


//=========================================================================================
//===== TEST receiving a request to take OSC Messages into account
//=========================================================================================
void switchToMessages(OSCMessage &mess) { manageBundles = 0; manageMessages = 1; }


//=========================================================================================
//===== TEST receiving an OSC Message made of the address "/led" and containing 2 ints : led number , led status (0=LOW , 1=HIGH)
//=========================================================================================
void setLEDStatus(OSCMessage &mess)
{
	if (mess.size() == 2 && mess.isInt(0) && mess.isInt(1)) {
		int thisLed = mess.getInt(0);
		int thisStatus = mess.getInt(1);

		if (thisLed == 0 && thisStatus == 0) {digitalWrite(led1,LOW);}
		else if (thisLed == 0 && thisStatus == 1) {digitalWrite(led1,HIGH);}
		else if (thisLed == 1 && thisStatus == 0) {digitalWrite(led2,LOW);}
		else if (thisLed == 1 && thisStatus == 1) {digitalWrite(led2,HIGH);}
		//	else {
		//		return;			// ERRORS : inappropriate led number or led status
		//	}
	}
	//	else {
	//		return;			// ERRORS : bad message size (!= 2) or the arguments are not ints
	//	}
}


//=========================================================================================
//===== TEST sending an OSCMessage (called when the Spark Core receives "/sendTestMsg" as an OSC Message)
//=========================================================================================
void sendOSCTestMsg(OSCMessage &mess)
{
	OSCMessage testMsg_toSend("/testmessage");
	testMsg_toSend.add((float)2.6).add(150).add("hahaha").add(-1000);

	Udp.beginPacket(computerIPAddress, REMOTEPORT);
	testMsg_toSend.send(Udp); // send the bytes
	Udp.endPacket();
	testMsg_toSend.empty(); // empty the message to free room for a new one
}

//=========================================================================================
//===== TEST sending an OSCBundle (called when the Spark Core receives "/sendTestBndl" as an OSC Message)
//=========================================================================================
void sendOSCTestBndl(OSCMessage &mess)
{
	OSCBundle testBndl_toSend;

	//OSCBundle's "add" returns the OSCMessage so the message's "add" can be composed together
	testBndl_toSend.add("/testbundle/msg1").add((float)5.6).add(250).add("hohoho").add(-2000);
	testBndl_toSend.add("/testbundle/msg2").add(124).add("hehehe").add((float)1.6).add(-150);

	testBndl_toSend.setTimetag((uint64_t)millis());
	// NB : millis() is "the number of milliseconds since the processor started up", not an appropriate NTP timetag !
	// setTimetag(oscTime()) DOESN'T WORK ON THE SPARK CORE (Oscuino has to rewrite the OSCTiming class)

	Udp.beginPacket(computerIPAddress, REMOTEPORT);
	testBndl_toSend.send(Udp); // send the bytes
	Udp.endPacket();
	testBndl_toSend.empty(); // empty the bundle to free room for a new one
}


//=========================================================================================
void loop()
{
	if (manageMessages == 1 && manageBundles == 0) {

		//===== TEST : receiving and dispatching an OSC Message

		OSCMessage testMsg_Received;

		int bytesToRead = Udp.parsePacket();	// how many bytes are available via UDP
		if (bytesToRead > 0) {
			while(bytesToRead--) {
				testMsg_Received.fill(Udp.read());	// filling the OSCMessage with the incoming data
			}
			if(!testMsg_Received.hasError()) { // if the address corresponds to a command, we dispatch it to the corresponding function
				testMsg_Received.dispatch(OscCmd_led , setLEDStatus);
				testMsg_Received.dispatch(OscCmd_TestSendMsg , sendOSCTestMsg);
				testMsg_Received.dispatch(OscCmd_TestSendBndl , sendOSCTestBndl);
				testMsg_Received.dispatch(OscCmd_SwtichToBundles , switchToBundles);
			}
			//	else {
			//		return;			// ERRORS : errors in the OSCMessage
			//	}
		}
	}

	else if (manageBundles == 1 && manageMessages == 0) {

		//===== TEST : receiving and dispatching an OSC Bundle (same code as with the OSCMessage, but with an OSCBundle)

		OSCBundle testBndl_Received;

		int bytesToRead = Udp.parsePacket();	// how many bytes are available via UDP
		if (bytesToRead > 0) {
			while(bytesToRead--) {
				testBndl_Received.fill(Udp.read());	// filling the OSCBundle with the incoming data
			}
			if(!testBndl_Received.hasError()) { // if the address corresponds to a command, we dispatch it to the corresponding function
				testBndl_Received.dispatch(OscCmd_led , setLEDStatus);
				testBndl_Received.dispatch(OscCmd_TestSendMsg , sendOSCTestMsg);
				testBndl_Received.dispatch(OscCmd_TestSendBndl , sendOSCTestBndl);
				testBndl_Received.dispatch(OscCmd_SwitchToMessages , switchToMessages);
			}
			//	else {
			//		return;			// ERRORS : errors in the OSCBundle
			//	}
		}
	}{
  //the message wants an OSC address as first argument
  OSCMessage msg("/analog/0");
  msg.add((int32_t)analogRead(0));
  
  Udp.beginPacket(computerIPAddress, REMOTEPORT);
    msg.send(Udp); // send the bytes to the SLIP stream
  Udp.endPacket(); // mark the end of the OSC Packet
  msg.empty(); // free space occupied by message

  delay(20);
  
}
  OSCMessage msg("/analog/1");
  msg.add((int32_t)analogRead(1));
  
  Udp.beginPacket(computerIPAddress, REMOTEPORT);
    msg.send(Udp); // send the bytes to the SLIP stream
  Udp.endPacket(); // mark the end of the OSC Packet
  msg.empty(); // free space occupied by message

  delay(20);
}

You should put this in setup since you will only need it once. I guess it is a little hard than what I wrote above since IPAddress does like assignments except from 8-bit arrays or 32-bit uints (ours is backwards).

void setup()
{
	// Initialize D0 + D1 pins as output for the two LEDs
	pinMode(led1, OUTPUT);
	pinMode(led2, OUTPUT);

        uint32_t ip_addr = 0; //TI CC3000 IP addresses are uint32 in reverse order
        char host[] = "www.myhost.com";  // your dyndns host name here

        if(gethostbyname(host, strlen(host), &ip_addr) > 0)   {
          computerAddress = { (uint8_t)BYTE_N(ip_addr, 3), 
                              (uint8_t)BYTE_N(ip_addr, 2), 
                              (uint8_t)BYTE_N(ip_addr, 1), 
                              (uint8_t)BYTE_N(ip_addr, 0) };
} else {
//report error didn't find it--flash the LEDs or something here!
}
...

If that doesn’t work for some reason, we can just set each byte individually instead. Sorry I can’t test it right now.

Hi bko
gave this a few goes but get these errors on compile :frowning:

Building file: …/src/application.cpp
Invoking: ARM GCC CPP Compiler
mkdir -p obj/src/
arm-none-eabi-gcc -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb -I…/inc -I…/inc/OSC -I…/…/core-common-lib/CMSIS/Include -I…/…/core-common-lib/CMSIS/Device/ST/STM32F10x/Include -I…/…/core-common-lib/STM32F10x_StdPeriph_Driver/inc -I…/…/core-common-lib/STM32_USB-FS-Device_Driver/inc -I…/…/core-common-lib/CC3000_Host_Driver -I…/…/core-common-lib/SPARK_Firmware_Driver/inc -I…/…/core-communication-lib/lib/tropicssl/include -I…/…/core-communication-lib/src -I. -ffunction-sections -Wall -fmessage-length=0 -MD -MP -MF obj/src/application.o.d -DUSE_STDPERIPH_DRIVER -DSTM32F10X_MD -DDFU_BUILD_ENABLE -DRELEASE_BUILD -fno-exceptions -fno-rtti -c -o obj/src/application.o …/src/application.cpp
In file included from …/src/application.cpp:2:0:
…/inc/OSC/OSCMessage.h:33:7: warning: extra tokens at end of #else directive
#else if SPARK
^
…/src/application.cpp:39:15: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
int offset = 0;
^
…/src/application.cpp: In function ‘void setup()’:
…/src/application.cpp:74:11: error: ‘computerAddress’ was not declared in this scope
computerAddress = { (uint8_t)BYTE_N(ip_addr, 3),
^
…/src/application.cpp:77:59: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
(uint8_t)BYTE_N(ip_addr, 0) };
^
…/src/application.cpp:86:18: error: ‘computerIPAddress’ was not declared in this scope
Udp.beginPacket(computerIPAddress, REMOTEPORT);
^
…/src/application.cpp:98:40: error: a function-definition is not allowed here before ‘{’ token
void switchToBundles(OSCMessage &mess) { manageMessages = 0; manageBundles = 1;}
^
…/src/application.cpp:104:41: error: a function-definition is not allowed here before ‘{’ token
void switchToMessages(OSCMessage &mess) { manageBundles = 0; manageMessages = 1; }
^
…/src/application.cpp:111:1: error: a function-definition is not allowed here before ‘{’ token
{
^
…/src/application.cpp:235:1: error: expected ‘}’ at end of input
}
^
make: *** [obj/src/application.o] Error 1

BUILD FAILED (exit value 2, total time: 18s)