Difference between revisions of "LSL Protocol/OpenRadioCommunication"
Jump to navigation
Jump to search
Line 180: | Line 180: | ||
SendInt(5,5000); //This will add a 5 digit long integer, containing the value 5000 to the buffer. | SendInt(5,5000); //This will add a 5 digit long integer, containing the value 5000 to the buffer. | ||
SendASCIIWord("Hello world!"); //This will add an ASCII encoded string of variable length to the sending buffer. | SendASCIIWord("Hello world!"); //This will add an ASCII encoded string of variable length to the sending buffer. | ||
SendEnd(105.5, | SendEnd(105.5,POWER_MED); //This will send the buffer over channel 105.5 with the "medium" power setting (10 meters range) | ||
} | } | ||
</source> | </source> |
Revision as of 06:51, 10 October 2015
Open Radio Communication (ORC for short) Is a "binary like" radio system designed for small simple applications, where part of the goal is to have equipments interfere with eachothers.
Channels
The channels used by ORC go from -797386 to -797186 with 200 independent frequencies.
Frequency "friendly" numbers go from 88.1 to 108.1.
API
$module ()
//Open Radio System v0.1
integer POWER_LOW = 0;//whisper
integer POWER_MED = 1;//say
integer POWER_HI = 2;//shout
integer POWER_MAX = 3;//region
integer CHANNEL = -798267; //ORC in decimal basically
integer giSubchannel;
//This function is used to trim/pad data to length
string Size(integer iData,integer iBytes)
{
string s = (string)iData;
while(llStringLength(s)<iBytes)
s = "0"+s;
if(llStringLength(s)>iBytes)
s = llGetSubString(s,-iBytes,-1);
return s;
}
//////////////////////////////////////////RECEIVER//////////////////////////////////////////
//Functions to listen and read an OpenRC datastream //
//////////////////////////////////////////RECEIVER//////////////////////////////////////////
integer giReceiverPointer;
integer giReceiverHandle = -1;
integer Receiver(float fFrequency)
{
integer iFrequency = llAbs((integer)(fFrequency*10));
//set frequency to zero to turn receiver off.
if(iFrequency == 0)
{
if(giReceiverHandle != -1)
llListenRemove(giReceiverHandle);
giReceiverHandle = -1;
return -1;
}
// 88.1 to 108.1 expressed as 881 to 1081 -> 200 possible frequencies
if(iFrequency < 881)
iFrequency = 881;
else if(iFrequency > 1081)
iFrequency = 1081;
if(giReceiverHandle != -1)
llListenRemove(giReceiverHandle);
giSubchannel = CHANNEL+iFrequency;
giReceiverHandle = llListen(giSubchannel,"","","");
return iFrequency;
}
ReceiverInit()
{
//init basically set the pointer to 0
giReceiverPointer = 0;
}
string ReceiverRead(string sDatastream,integer iBytes)
{
//Main stream reader, read the number of bytes and move the pointer forward.
string sData = llGetSubString(sDatastream,giReceiverPointer,giReceiverPointer + iBytes - 1);
giReceiverPointer+=iBytes;
return sData;
}
integer ReceiverReadInt(string sDatastream,integer iBytes)
{
return (integer)ReceiverRead(sDatastream,iBytes);
}
string ReceiverReadASCIIChar(string sDatastream)
{
return ASCII2Char(ReceiverReadInt(sDatastream,3));
}
string ReceiverReadASCIIWord(string sDatastream)
{
//first we attempt to read the header (charcount)
integer iLength = ReceiverReadInt(sDatastream,3);
if(iLength < 1)
iLength = 0;
string sBuffer = "";
integer i;
for(i=0;i<iLength;i++)
sBuffer += ReceiverReadASCIIChar(sDatastream);
return sBuffer;
}
//////////////////////////////////////////SENDER//////////////////////////////////////////
//Functions to build and send an OpenRCsend datastream //
//////////////////////////////////////////SENDER//////////////////////////////////////////
string gsSendBuffer;
//Execute before building a datastream to ensure that the send buffer is clean.
SendInit()
{
gsSendBuffer = "";
}
//Used to add an integer to the datastream, only positive values, you can pick the number of bytes used
SendInt(integer iValue,integer iBytes)
{
gsSendBuffer += Size(llAbs(iValue),iBytes);
}
//Used to add an ASCII character to the datastream, each ascii char always use 3 bytes.
SendASCIIChar(string sChar)
{
gsSendBuffer += Char2ASCII(sChar);
}
//Used to add an ASCII word to the datastream, words use 3 bytes per character and 3 extra bytes as header.
SendASCIIWord(string sWord)
{
//count the number of chars
integer iCount = llStringLength(sWord) % 999; //max word size is 999 chars because 3 bytes max.
integer i;
SendInt(iCount,3); //header of a word is it's total character count.
for(i=0;i<iCount;i++)
SendASCIIChar(llGetSubString(sWord,i,i));
}
//Send the buffer and purge it's content, you have to set power and frequency here.
SendEnd(float fFrequency,integer iPower)
{
integer iChannel = llAbs((integer)(fFrequency*10));
// 88.1 to 108.1 expressed as 881 to 1081 -> 200 possible frequencies
if(iChannel < 881)
iChannel = 881;
else if(iChannel > 1081)
iChannel = 1081;
iChannel += CHANNEL;
if(gsSendBuffer == "")
return;
if(iPower == POWER_LOW)
llWhisper(iChannel,gsSendBuffer);
else if(iPower == POWER_HI)
llShout(iChannel,gsSendBuffer);
else if(iPower == POWER_MAX)
llRegionSay(iChannel,gsSendBuffer);
else
llSay(iChannel,gsSendBuffer);
gsSendBuffer = "";
}
//////////////////////////////////////////CODEC//////////////////////////////////////////
//this is a basic ASCII coder/decoder toolset for char/word //
//////////////////////////////////////////CODEC//////////////////////////////////////////
//Conversion table to extended ascii, character index + 1 = value.
// 1 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 210 220 230 240 250 255 (nbsp)
string ASCII = "☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´±‗¾¶§÷¸°¨·¹³²■ ";
//Turns the supplied character into a 3 byte integer.
string Char2ASCII(string sData)
{
return Size(llSubStringIndex(ASCII,llGetSubString(sData,0,0)) + 1,3);
}
//Turns the supplied integer into it's corresponding character. values wrap around at ORC_ASCII length.
string ASCII2Char(integer iCharcode)
{
iCharcode = llAbs(iCharcode) % (llStringLength(ASCII)+1);
if(iCharcode <= 0)
return "";
iCharcode--; //shifting of 1 to account for the "" that is at position zero.
return llGetSubString(ASCII,iCharcode,iCharcode);
}
Examples
Sending a simple text message with the API
state_entry()
{
SendInit(); //Required before any transmission to setup the radio systems.
SendInt(5,5000); //This will add a 5 digit long integer, containing the value 5000 to the buffer.
SendASCIIWord("Hello world!"); //This will add an ASCII encoded string of variable length to the sending buffer.
SendEnd(105.5,POWER_MED); //This will send the buffer over channel 105.5 with the "medium" power setting (10 meters range)
}
Receiving a messages with the API
state_entry()
{
Receiver(105.5); //Will start listening for messages on channel 105.5
}
listen(integer channel,string name,key id,string datastream)
{
if(channel = giSubchannel && giReceiverHandle != -1)
{
ReceiverInit(); //setup the ORC system for reading the datastream
integer value = ReceiverReadInt(datastream,5); //read an Integer value of 5 digits.
string text = ReceiverReadASCIIWord(datastream); //read a variable length Ascii word.
}
}