Difference between revisions of "Ethernet multi-function Interface"
m (→IR frames format) |
m (→What you can do: read/write micom...) |
||
| Line 7: | Line 7: | ||
* Send IR codes to your TV, PVR or BD, with an URL in your browser | * Send IR codes to your TV, PVR or BD, with an URL in your browser | ||
* Use telnet to have the Serial Console on your PC or smartphone | * Use telnet to have the Serial Console on your PC or smartphone | ||
| − | * Read your config eeprom | + | * Read your SoC config eeprom |
| + | * Read/write micom config eeprom | ||
* See Arduino as a Samsung device in the Samsung Remote App (can be used to power on the device !) | * See Arduino as a Samsung device in the Samsung Remote App (can be used to power on the device !) | ||
Revision as of 11:59, 12 January 2013
Using an Arduino Ethernet board, you can send IR codes to your TV or BD
With the same board, you can also interface to the Serial Console, and read your device config eeprom.
Contents
What you can do
- Send IR codes to your TV, PVR or BD, with an URL in your browser
- Use telnet to have the Serial Console on your PC or smartphone
- Read your SoC config eeprom
- Read/write micom config eeprom
- See Arduino as a Samsung device in the Samsung Remote App (can be used to power on the device !)
Bill of materials
- Arduino Ethernet board (see Arduino)
Alternatively, an Arduino Uno with an Ethernet shield could also be used
- IR led (SFH4510 for example) or RED Led (Clear Type RED LED's are emitting more than enough light at IR spectrum)
- 220 ohms resistor to limit current in the IR led
- If you plan to use the telnet interface to the Serial Console, make sure you have a 100 ohms resistor on both RX and TX signals (Arduino TX/RX are 5v !)
How to use it
- Upload the following sketch into your Arduino
- Connect the IR or RED led with its resistor on pin 8 on the Arduino
- Connect power and network
- Find the IP address of the board on your DHCP (or use the static IP embedded in the sketch if you don't have DHCP)
- Use your browser to send an URL to the board (see format below)
- If you want to use telnet to connect to the Serial Console :
* Connect your Serial Console signals TX&RX to the Arduino board pins 0&1 (with 100 ohms resistors) * Use Putty with options 'Local Echo' and 'Local line editing' forced to OFF
- If you want to read your config eeprom :
* Connect the eeprom SDA&SCK signals to the Arduino board pins A4/A5 (with a 100 ohms resistors) * Connect the eeprom GND to 0v
- If you want to use the Samsung Remote feature :
* Compile with SAMSUNGREMOTE defined * The program only handles BD_KEY_POWER; if you want aditional keys, it's easy to add them
URL format to send IR codes
The format is http://IP/ir.htm?data=XX&type=Y&device=ZZZZ where
- IP is the Arduino board IP address
- XX is the IR code to send
- Y is 0 for TV/PVR frame format and 1 for BD frame format
- ZZZZ is the device code (0707 for TV, 0505 for PVR, 301A for BD)
The IR codes are listed at Key codes
- For TV/PVR, use the 'code' column
- For BD, use the 'BD-IR code' column
For example:
To get the Service Menu on your TV, use the 2 following URLs :
Please note that you cannot send KEY_FACTORY to a BD, as the corresponding code is not know yet
To have a kind of Wake Up on LAN on your BD player, use
To switch to channel 1 :
- On a TV : http://IP/ir.htm?data=65&type=0&device=0707
- On a BD : http://IP/ir.htm?data=81&type=0&device=301A
URL format to read config Eeprom
The format is http://IP/read?format=F&device=D&addr=A&size=S&width=W
- IP is the Arduino board IP address
- F is 0 to get the result in html, 1 to download a binary file
- D is the Eeprom device identification (80 by default)
- A is the starting address for reading (0 by default)
- S is the number of bytes to read (default=256)
- W is the address bus width (8 bits for Micom eeprom, 16 bits for SoC eeprom); default is 16
For example:
BD-E8300 is equiped with a 24512 eeprom (64 kbytes)
To download its whole config :
or :
Eeprom connection :
URL format to write config Eeprom
The format is http://IP/write?device=D&addr=A&data=X&width=W
- IP is the Arduino board IP address
- D is the Eeprom device identification (80 by default)
- A is the starting address for writing (0 by default)
- X is the data byte to write
- W is the address bus width (8 bits for Micom eeprom, 16 bits for SoC eeprom); default is 16
On this version, it is only possible to write one byte at once...
For example: http://IP/write?addr=e0&data=55&width=16 will write 0x55 at address 0xe0
IR frames format
BD players use a modified IR frame format that TV and PVR. The reason is that samsung increased the data field length from 8 to 12 bits The general format is now :
- Start bit
- Device ID (16 bits - 0707 for TV, 301A for BD)
- For BD only : Stop bit and data MSB on 4 bits
- Data LSB
- Data LSB 1's complement
A frame for BD :
Arduino sketch
This sketch has been compiled with Arduino 1.0.3 (Download here)
// ---------------------------------------------------------------------
// Samsung multi-functions ethernet interface
// - Send IR frame with http get requests
// - Debug console on telnet
// - Read & Write I2C config eeprom
//
// 29-06-2012 / v1.1 / oga83
// 11-09-2012 / v1.1 / oga83
// Added optionnal 'crc' url parameter for testing IR (allow to force CRC)
// Added I2C interface to read/write config eeprom
// 09-01-2013 / v1.1.1 / oga83
// Fixed compilation issue with Arduino 1.0.3 and typo in wiki
// 11-01-2013 / v1.1.2 / oga83
// Modified ReadEeprom and WriteEeprom for 1-byte address eeproms
// 11-01-2013 / v1.2 / oga83
// Added Samsung Remote protocol (Arduino seen as a samsung device)
//----------------------------------------------------------------------
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Wire.h>
#define IRPIN 8 // IR led is connected on pin 8
#define LEDPIN 9 // Onboard led - blink at 2 Hz
// Debug console TX signal connected on 0
// Debug console RX signal connected on 1
// I2C Eeprom : SDA connected on A4
// I2C Eeprom : SCK connected on A5
byte mac[] = { 0x90, 0xA2, 0xda, 0x00, 0xe6, 0x5e }; // Arduino Ethernet board MAC address
IPAddress ip(192,168,1,178); // Default static IP if no DHCP
EthernetServer HttpServer(80); // HTTP is used to send IR commands
EthernetServer TelnetServer(23); // Telnet is used for Serial Console
#define SAMSUNGREMOTE // if defined, Arduino will be seen as a Samsung device
#ifdef SAMSUNGREMOTE
EthernetServer SamsungRemote(55000); // Emulates a Samsung device
EthernetUDP SamsungSSDP; // Handles Samsung device discovery
#endif
// ---------------------------------------------------------------------
// Utilities
// ---------------------------------------------------------------------
// Convert a hex string to unsigned int
unsigned int HexToULong(char *s)
{
unsigned long u=0;
while (*s)
{
char c=*s++;
// Convert to uppercase
if (c>='a') c&=0xdf;
// Exit if not hex digit
if ((c<'0' || c>'9') && (c<'A' || c>'F')) break;
// Convert digit
u<<=4;
u|=c-((c>'9') ? 'A'-0xa:'0');
}
return u;
}
#ifdef SAMSUNGREMOTE
// Base64 conversion
const char *sBase64TranslateTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+%";
void AsciiToBase64(char *Ascii, char *Buffer, int BufferSize)
{
int Length=0;
while (*Ascii)
{
unsigned long s32bits=0;
int i, j;
// Read 3 ASCII bytes
for (i = 2; i >= 0; i--)
{
if (*Ascii==0) break;
s32bits |= ((unsigned long)*Ascii++)<<(8*i);
}
// Convert them to four 6-bit items
for (j=3; j>=i+1; j--)
{
// Check for buffer overflow
if (++Length>=BufferSize) { *Buffer=0; return; }
// Convert 6-bit item
int c = ((s32bits >> (6 * j)) & 0x3f);
*Buffer++ = sBase64TranslateTable[c];
}
// Complete last bytes
for (/*void*/; j>=0 && ++Length<BufferSize; j--) *Buffer++='=';
}
*Buffer=0; // Trailing 0 is not needed for this project, but simplify testing
}
void Base64ToAscii(char *Base64, char *Buffer, int BufferSize)
{
int Length=0;
while (*Base64 && *Base64!='=')
{
unsigned long s24bits = 0;
// Read four 6-bit items
for (int i=3; i>=0; i--)
{
if (*Base64==0 || *Base64=='=') break;
char *p=strchr(sBase64TranslateTable, *Base64++);
if (p) s24bits |= ((unsigned long)(p-sBase64TranslateTable))<<(6*i);
}
// Convert them to three 8-bit items
for (int i=2; i>=0; i--)
{
// Check for buffer overflow
if (++Length>=BufferSize) break;
// Save byte
*Buffer++ = (char)((s24bits>>(8*i))&0xff);
}
}
*Buffer=0;
}
unsigned DecodeSamsungProtocolString(char *s, char *Buffer, int BufferSize, boolean bBase64)
{
// Get length of string in message
unsigned Length=s[0] | (((unsigned)s[1])<<8);
// Get the string
if (bBase64)
{
// Force trailing 0 into Base64 string
// (dirty but will work in this project, as the Base64 string is in a frame buffer...)
char c=s[Length+2]; s[Length+2]=0;
Base64ToAscii(s+2, Buffer, BufferSize);
// Restore corrupted char
s[Length+2]=c;
}
else
{
// Check for buffer overflow
unsigned MaxLength=(Length>BufferSize-1) ? BufferSize-1:Length;
// Just copy string
strncpy(Buffer, s+2, MaxLength);
Buffer[MaxLength]=0;
}
// Returns length of initial buffer
return Length+2;
}
unsigned EncodeSamsungProtocolString(char *s, char *Buffer, int BufferSize, boolean bBase64)
{
unsigned Length;
if (bBase64)
{
// Encode string in Base64
AsciiToBase64(s, Buffer+2, BufferSize-2);
Length=strlen(Buffer+2);
}
else
{
// Leave string in Ascii - No trailing 0
Length=strlen(s);
if (Length>BufferSize-2) Length=BufferSize-2;
strncpy(Buffer+2, s, Length);
}
// Add size of string in message
Buffer[0]=Length; Buffer[1]=Length>>8;
return Length+2;
}
#endif
// ---------------------------------------------------------------------
// Samsung IR class
// ---------------------------------------------------------------------
class Samsung
{
private:
// Send a 36kHz-modulated pulse
static void Pulse(void)
{
byte i;
for (i=0; i<21; i++)
{
digitalWrite(IRPIN, HIGH);
delayMicroseconds(10); // Value adjusted with oscilloscope
digitalWrite(IRPIN, LOW);
delayMicroseconds(10); // Value adjusted with oscilloscope
}
}
// Send a bit
static void SendIRBit(byte b)
{
Pulse();
if (b)
delayMicroseconds(1390);
else
delayMicroseconds(430);
}
// Send 4 bits
static void SendIRNibble(byte b)
{
byte i;
for (i=0; i<4; i++)
SendIRBit((b>>i)&1);
}
// Send a byte
static void SendIRByte(byte b)
{
byte i;
for (i=0; i<8; i++)
SendIRBit((b>>i)&1);
}
public:
// Send an IR command
// Type is 0 for TV, 1 for BD
// Device is 0x0707 for TV, 0x301A for BD
// Crc should be ~Command, except for tests
static void SendCommand(char Type, unsigned int Device, unsigned int Command, unsigned char Crc)
{
byte i;
// Disable interrupts
cli();
// Start bit
for (i=0; i<8; i++) Pulse();
delayMicroseconds(4500);
// Send Device Id
SendIRByte(Device>>8);
SendIRByte(Device&0xff);
// BD Player
if (Type==1)
{
// Stop bit
Pulse();
delayMicroseconds(4500);
// Send Data
SendIRNibble(Command>>8);
}
SendIRByte(Command);
SendIRByte(Crc);
// Stop bit
Pulse();
delayMicroseconds(4500);
// Re-enable interrupts
sei();
}
// Read Eeprom
static void ReadEeprom(byte device, long addr, byte *data, int count)
{
if (addr!=0xffffffff)
{
Wire.beginTransmission(device);
if (bEeprom2ByteAddress) Wire.write(addr>>8);
Wire.write(addr);
Wire.endTransmission();
}
Wire.requestFrom((int)device, count);
for (int i=0; i<count; i++)
{
if (!Wire.available()) break;
data[i]=Wire.read();
}
}
// Write Eeprom
static void WriteEeprom(byte device, long addr, byte *data, int count)
{
Wire.beginTransmission(device);
if (bEeprom2ByteAddress) Wire.write(addr>>8);
Wire.write(addr);
for (int i=0; i<count; i++) Wire.write(data[i]);
Wire.endTransmission();
}
static boolean bEeprom2ByteAddress;
};
boolean Samsung::bEeprom2ByteAddress=true;
// ---------------------------------------------------------------------
// Initialization
// ---------------------------------------------------------------------
void setup()
{
// Led
pinMode(LEDPIN, OUTPUT);
digitalWrite(LEDPIN, HIGH);
// IR Led
pinMode(IRPIN, OUTPUT);
digitalWrite(IRPIN, HIGH);
// I2C
Wire.begin();
// Serial Console
Serial.begin(115200);
// Initialize Ethernet. Try DHCP, otherwise static IP
if (Ethernet.begin(mac)==0)
Ethernet.begin(mac, ip);
// Initialize HTTP server
HttpServer.begin();
// Initialize Telnet server
TelnetServer.begin();
#ifdef SAMSUNGREMOTE
// Initialize Samsung Remote server
SamsungRemote.begin();
// Initialize SSDP
SamsungSSDP.begin(1900);
#endif
}
// ---------------------------------------------------------------------
// Main Program
// ---------------------------------------------------------------------
char HttpFrame[256]; // General buffer for Http and Samsung protocol frames
char TelnetFrame[256]; // General buffer for Telnet frames
char Buffer[32]; // General buffer
boolean iStateLed=false; // Used for led blinking
unsigned long timeLastLedMs=0; // Used for blinking delay
void loop()
{
// -------------------------------------------------
// LED blinks at 2Hz
// -------------------------------------------------
if (millis()>timeLastLedMs+250)
{
timeLastLedMs=millis();
digitalWrite(LEDPIN, (iStateLed) ? HIGH:LOW);
iStateLed=!iStateLed;
}
// -------------------------------------------------
// Handle HTTP requests
// Example :
// To send KEY_1 on BD :
// http://IP/ir.htm?data=81&type=1&device=301a
// -------------------------------------------------
EthernetClient client = HttpServer.available();
if (client)
{
char *ptr=HttpFrame;
int n=0;
while (client.connected() && client.available())
{
if (n++<sizeof(HttpFrame))
*ptr++=client.read();
else
client.flush();
}
*ptr=0;
if (n>0)
{
const __FlashStringHelper *HtmlHeader=F("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n");
// -------------------------------------------------
// Send Samsung IR command
// -------------------------------------------------
ptr=strstr(HttpFrame, "/ir.htm?");
if (ptr)
{
byte Type=0, Crc;
unsigned int Device=0x0707, Data=0;
ptr=strstr(HttpFrame, "data=");
if (ptr) Data=HexToULong(ptr+5);
ptr=strstr(HttpFrame, "type=");
if (ptr) Type=HexToULong(ptr+5);
ptr=strstr(HttpFrame, "device=");
if (ptr) Device=HexToULong(ptr+7);
// Next parameter is optional and can be used for tests
Crc=~Data;
ptr=strstr(HttpFrame, "crc=");
if (ptr) Crc=HexToULong(ptr+4);
Samsung::SendCommand(Type, Device, Data, Crc);
client.println(HtmlHeader);
client.println("OK !");
client.stop();
return;
}
// -------------------------------------------------
// Read Eeprom
// -------------------------------------------------
ptr=strstr(HttpFrame, "/read");
if (ptr)
{
byte Device=0, Format=0x50;
unsigned long Size=0x100, Addr=0;
ptr=strstr(HttpFrame, "addr=");
if (ptr) Addr=HexToULong(ptr+5);
ptr=strstr(HttpFrame, "size=");
if (ptr) Size=atol(ptr+5);
ptr=strstr(HttpFrame, "device=");
if (ptr) Device=atoi(ptr+7);
ptr=strstr(HttpFrame, "format=");
if (ptr) Format=atoi(ptr+7);
ptr=strstr(HttpFrame, "width=8");
Samsung::bEeprom2ByteAddress=(ptr==0);
if (Format==0)
{
client.println("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n");
}
else
client.println("HTTP/1.1 200 OK\r\nContent-Type: binary/octet-stream\r\n");
byte bSequential=0;
for (long i=Addr; i<Addr+Size; i+=32)
{
unsigned char Data[32];
for (int i=0; i<32; i++) Data[i]=0xff;
Samsung::ReadEeprom(Device, (bSequential) ? -1:i, Data, 32);
bSequential=1;
if (Format==0)
{
sprintf(Buffer, "%04lx: ", i); client.print(Buffer);
for (int j=0; j<32; j++)
{ sprintf(Buffer, "%02X ", Data[j]); client.print(Buffer); }
for (int j=0; j<32; j++)
{ client.write((Data[j]<=0x20 || Data[j]>0x7f) ? '.':Data[j]); }
client.println("");
client.flush();
}
else
{
for (int j=0; j<32; j++)
client.write(Data[j]);
}
}
client.stop();
return;
}
// -------------------------------------------------
// Write Eeprom
// -------------------------------------------------
ptr=strstr(HttpFrame, "/write");
char *ptrAddr=strstr(HttpFrame, "addr=");
char *ptrData=strstr(HttpFrame, "data=");
if (ptr && ptrAddr && ptrData)
{
byte Device=0, Data;
unsigned long Addr;
Addr=HexToULong(ptrAddr+5);
Data=HexToULong(ptrData+5);
ptr=strstr(HttpFrame, "device=");
if (ptr) Device=atoi(ptr+7);
ptr=strstr(HttpFrame, "width=8");
Samsung::bEeprom2ByteAddress=(ptr==0);
Samsung::WriteEeprom(Device, Addr, &Data, 1);
client.println("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n");
Data=~Data;
Samsung::ReadEeprom(Device, Addr, &Data, 1);
sprintf(Buffer, "%02X ", Data);
client.print(Buffer);
client.stop();
return;
}
#ifdef SAMSUNGREMOTE
// -------------------------------------------------
// Device info - used for Samsung Remote Protocol
// -------------------------------------------------
ptr=strstr(HttpFrame, "/smp_2_");
if (ptr)
{
client.println(F("HTTP/1.1 200 OK\r\nContent-Type: text/xml\r\n"));
client.println(F("<?xml version=\"1.0\"?>"));
client.println(F("<root xmlns='urn:schemas-upnp-org:device-1-0' xmlns:sec='http://www.sec.co.kr/dlna' xmlns:dlna='urn:schemas-dlna-org:device-1-0'>"));
client.println(F(" <specVersion>"));
client.println(F(" <major>1</major>"));
client.println(F(" <minor>0</minor>"));
client.println(F(" </specVersion>"));
client.println(F(" <device>"));
client.println(F(" <deviceType>urn:samsung.com:device:RemoteControlReceiver:1</deviceType>"));
client.println(F(" <friendlyName>SamyGO</friendlyName>"));
client.println(F(" <manufacturer>Samsung Electronics</manufacturer>"));
client.println(F(" <manufacturerURL>http://www.samsung.com/sec</manufacturerURL>"));
client.println(F(" <modelDescription>Samsung BD RCR</modelDescription>"));
client.println(F(" <modelName>BD-E8500</modelName>"));
client.println(F(" <modelNumber>1.0</modelNumber>"));
client.println(F(" <modelURL>http://www.samsung.com/sec</modelURL>"));
client.println(F(" <serialNumber>12345678RCR</serialNumber>"));
client.println(F(" <UDN>uuid:11111111-2222-3333-4444-555555555555</UDN>"));
client.println(F(" <sec:deviceID>ABCDEFGHIJKLM</sec:deviceID>"));
client.println(F(" <sec:ProductCap>Resolution:1280X720,ImageZoom,ImageRotate,Y2012</sec:ProductCap>"));
client.println(F(" <serviceList>"));
client.println(F(" <service>"));
client.println(F(" <serviceType>urn:samsung.com:service:TestRCRService:1</serviceType>"));
client.println(F(" <serviceId>urn:samsung.com:serviceId:TestRCRService</serviceId>"));
client.println(F(" <controlURL>/smp_4_</controlURL>"));
client.println(F(" <eventSubURL>/smp_5_</eventSubURL>"));
client.println(F(" <SCPDURL>/smp_3_</SCPDURL>"));
client.println(F(" </service>"));
client.println(F(" </serviceList>"));
client.println(F(" </device>"));
client.println(F("</root>"));
client.stop();
return;
}
#endif
// send an error !
client.println(HtmlHeader);
client.println(F("Error !"));
delay(1);
}
client.stop();
}
#ifdef SAMSUNGREMOTE
// -------------------------------------------------
// Samsung Remote Protocol
// -------------------------------------------------
client = SamsungRemote.available();
if (client)
{
//Serial.println("Incoming frame...");
// Read incoming frame
char *ptr=HttpFrame;
int n=0;
while (client.connected() && client.available())
if (n++<sizeof(HttpFrame)) *ptr++=client.read();
ptr=HttpFrame+1;
// Decode App Name
ptr+=DecodeSamsungProtocolString(ptr, Buffer, sizeof(Buffer), false);
//Serial.print("Name="); Serial.println(Buffer);
// Ignore message length
ptr+=2;
// Decode command
unsigned Cmd=*ptr++; Cmd|=(*ptr++)<<8;
//Serial.print("Cmd="); Serial.println(Cmd);
// Connection frame ?
if (Cmd==0x64)
{
// Decode remote IP
ptr+=DecodeSamsungProtocolString(ptr, Buffer, sizeof(Buffer), true);
//Serial.print("IP="); Serial.println(Buffer);
// Decode remote MAC address
ptr+=DecodeSamsungProtocolString(ptr, Buffer, sizeof(Buffer), true);
//Serial.print("MAC="); Serial.println(Buffer);
// Decode machine name
ptr+=DecodeSamsungProtocolString(ptr, Buffer, sizeof(Buffer), true);
//Serial.print("Machine="); Serial.println(Buffer);
delay(5);
}
// Key frame ?
else if (Cmd==0x00)
{
ptr++; // Skip first byte
ptr+=DecodeSamsungProtocolString(ptr, Buffer, sizeof(Buffer), true);
//Serial.print("KeyName="); Serial.print(Buffer); Serial.println("----");
if (!strcmp(Buffer, "BD_KEY_POWER"))
{
// Power key for BD
Samsung::SendCommand(1, 0x301a, 0x91, ~0x91);
}
}
// Answer
HttpFrame[0]=0;
int len=1;
len+=EncodeSamsungProtocolString("iapp.samsung", HttpFrame+1, sizeof(HttpFrame), false);
if (Cmd==0x64)
{
byte answer[]={0x04,0x00,0x64,0x00,0x01,0x00};
memcpy(HttpFrame+len, answer, sizeof(answer));
len+=sizeof(answer);
}
else
{
byte answer[]={0x04,0x00,0x00,0x00,0x00,0x00};
memcpy(HttpFrame+len, answer, sizeof(answer));
len+=sizeof(answer);
}
client.write((byte *)HttpFrame, len);
delay(5);
}
// SSDP discovery protocol
int PacketSize=SamsungSSDP.parsePacket();
if (PacketSize)
{
// Read incoming frame
char *ptr=HttpFrame;
int n=0;
while (SamsungSSDP.available())
if (n++<sizeof(HttpFrame)) *ptr++=SamsungSSDP.read();
// Discovery request ?
if (strstr(HttpFrame, "M-SEARCH *") && strstr(HttpFrame, "urn:samsung.com:device:RemoteControlReceiver:1"))
{
//Serial.print("SSDP Discovery from : IP="); Serial.print(SamsungSSDP.remoteIP()); Serial.print(":"); Serial.println(SamsungSSDP.remotePort());
SamsungSSDP.beginPacket(SamsungSSDP.remoteIP(), SamsungSSDP.remotePort());
SamsungSSDP.println(F("HTTP/1.1 200 OK"));
SamsungSSDP.println(F("CACHE-CONTROL: max-age= 1800"));
SamsungSSDP.println(F("Date: Sat, 01 Jan 2012 00:00:00 GMT"));
SamsungSSDP.println(F("EXT: "));
SamsungSSDP.print(F("LOCATION: http://")); SamsungSSDP.print(Ethernet.localIP()); SamsungSSDP.println(F(":80/smp_2_"));
SamsungSSDP.println(F("SERVER: SHP, UPnP/1.0, Samsung UPnP SDK/1.0"));
SamsungSSDP.println(F("ST: urn:samsung.com:device:RemoteControlReceiver:1"));
SamsungSSDP.println(F("USN: uuid:11111111-2222-3333-4444-555555555555::urn:samsung.com:device:RemoteControlReceiver:1"));
SamsungSSDP.println(F("Content-Length: 0"));
SamsungSSDP.endPacket();
}
}
#endif
// -------------------------------------------------
// Telnet Serial Console Interface
// Configure Putty with :
// - "Local Echo : Force off"
// - "Local line editing : Force off"
// -------------------------------------------------
client = TelnetServer.available();
if (client)
{
char *ptr=TelnetFrame;
int n=0;
while (client.connected() && client.available())
if (n++<sizeof(TelnetFrame)) *ptr++=client.read();
*ptr=0;
// Sends telnet buffer to Serial Console
if (n>0) Serial.write(TelnetFrame);
}
// Anything received from Serial Console ?
char *ptr=TelnetFrame;
int n=0;
while (Serial.available())
if (n++<sizeof(TelnetFrame)) *ptr++=Serial.read();
*ptr=0;
// Send it to telnet
if (n>0) TelnetServer.write(TelnetFrame);
}
// ---------------------------------------------------------------------
References
Any discussion on related forum topic.
