Page 1 of 2

Remote Control CLI (included c source)

Posted: Fri Apr 12, 2013 2:07 am
by TRiXWooD
A Command Line Interface Remote Control for Samsung TV's (source only)
Have phun! :D
TRiXWooD

SpoilerShow

Code: Select all

/*
 *   SamsungTV Remote C++ Command Line Interface v0.01 April 2013 TRiXWooD (cris.wood.org -AD- gmail.com)
 *
 *   Network Error Handling (Mostly Missing)
 *   Key &| Text Input Checking some chars will result in disabling the tv's remote part
 *   Compiles with gcc (tested under osx)
 *
 */

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>

int samsungtv_encodeblock(char *input, char *output, int oplen){
    int rc = 0, iplen = 0;
    char encodedstr[5] = "";
    char encodingtabe[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    iplen = strlen(input);
    encodedstr[0] = encodingtabe[ input[0] >> 2 ];
    encodedstr[1] = encodingtabe[ ((input[0] & 0x03) << 4) | ((input[1] & 0xf0) >> 4) ];
    encodedstr[2] = (iplen > 1 ? encodingtabe[ ((input[1] & 0x0f) << 2) | ((input[2] & 0xc0) >> 6) ] : '=');
    encodedstr[3] = (iplen > 2 ? encodingtabe[ input[2] & 0x3f ] : '=');
    strncat(output, encodedstr, oplen-strlen(output));    
    return rc;
}

int samsungtv_base64encode(char *input, char *output, int oplen){
    int rc = 0;
    int index = 0, ipindex = 0, iplen = 0;
    char encoderinput[4] = "";
    iplen = strlen(input);
    while(ipindex < iplen){
        for(index = 0; index < 3; index++){
            if(ipindex < iplen)
                encoderinput[index] = input[ipindex];
            else
                encoderinput[index] = 0;
            
            ipindex++;
        }
        rc = samsungtv_encodeblock(encoderinput, output, oplen);
    }
    return rc;
}

int samsungtv_response(int net_socket) {
  unsigned char message[256];
  memset (message,0x00,256);
  int i = 3;
  recv(net_socket,message,3,0);
  recv(net_socket,message+i,message[1],0);
  i += message[1];
  recv(net_socket,message+i,2,0);
  i += 2;
  unsigned char response = message[i-2];
  recv(net_socket,message+i,response,0);
  i += response;
  if (message[i-4] == 0x00 && message[i-3] == 0x00 && message[i-2] == 0x00 && message[i-1] == 0x00)
      if (message[0] == 0x01) return 4;                       // success repeat keystroke...
      else return 0;                                          // success
  if (message[i-response] == 0x65) return 3;                  // timeoutt....
  if (message[i-4] == 0x64 && message[i-2] == 0x00) return 1; // access denied...
  if (message[i-4] == 0x64 && message[i-2] == 0x01) return 0; // success
  if (message[i-response] == 0x0A) return 2;                  // waiting for user...
  return -1;                                                  // bug!
}

int samsungtv_setlength(unsigned char message[], unsigned int length) {
    message[0] = (unsigned char) (length & 0xFF);
    message[1] = (unsigned char) ((length >> 8) & 0xFF);
}

int samsungtv_setstring(unsigned char message[],unsigned char string[],int base64) {
    unsigned char s[512];
    memset (s,0x00,512);
    if (base64 == 1) samsungtv_base64encode(string,s,strlen(string)*2);
    else strncpy(s,string,strlen(string));
    samsungtv_setlength(message,strlen(s));
    strncpy(message+2,s,strlen(s));
    return strlen(s)+2;
}

int samsungtv_message(unsigned char string[], int net_socket, int type) {
    unsigned char remote[] = "SamsungTVRemote";
    unsigned char message[1024];
    memset (message,0x00,1024);
    unsigned int s = samsungtv_setstring(message+1,"iphone.iapp.samsung",0) + 1;
    unsigned int i = s + 4 + (type==1?1:0);
    i += samsungtv_setstring(message+i,string,1);
    if (type == 0) {
        message[s+2] = 0x64;
        i += samsungtv_setstring(message+i,remote,1);
        i += samsungtv_setstring(message+i,remote,1);
    }
    if (type == 2) {
      message[0] = 0x01;
      message[s+2] = 0x01;
    }
    samsungtv_setlength(message+s,i-s-2);
    send(net_socket,message, i, 0);
    return (type==2?0:samsungtv_response(net_socket));
}

int samsungtv_authenticate(unsigned char ip[], int net_socket) { return samsungtv_message(ip,net_socket,0); }
int samsungtv_sendkey(unsigned char key[], int net_socket) { return samsungtv_message(key,net_socket,1); }
int samsungtv_sendtext(unsigned char text[], int net_socket) { return samsungtv_message(text,net_socket,2); }

int main(int argc, char *argv[]) {
    
    struct addrinfo hints, *res, *p;
    int net_status, net_socket;
    
    if (argc < 3 || argc > 4 || (argc == 4 && strcmp(argv[2],"-T") != 0) || (argc == 3 && strcmp(argv[2],"-T") == 0)) {
        printf("SamsungTV Remote Control CLI v0.01 April 2013 TRiXWooD\n");
        printf("usage: STVCLI IP KEY\n");
        printf("       STVCLI IP -T TEXT\n");
        return 1;
    }
    
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
    hints.ai_socktype = SOCK_STREAM;
        if ((net_status = getaddrinfo(argv[1],"55000", &hints, &res)) != 0) {
        fprintf(stderr, "SamsungTV Remote: Connection Failure: (%s)\n", gai_strerror(net_status));
        return 2;
    }
    net_socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if ((net_status = connect(net_socket, res->ai_addr, res->ai_addrlen)) != 0) {
        fprintf(stderr, "SamsungTV Remote: Connected Failure (%s)\n", gai_strerror(net_status));
        return 2;
    }
          
   int response,auth_status = samsungtv_authenticate(argv[1],net_socket);
    if (auth_status == 0) {
      if (strcmp(argv[2],"-T") == 0)
        response = samsungtv_sendtext(argv[3],net_socket);
      else
        response = samsungtv_sendkey(argv[2],net_socket);
        if (response != 0 && response != 4) fprintf(stderr, "SamsungTV Remote: Bug!\n");
        }
    else
    { if (auth_status == -1) fprintf(stderr, "SamsungTV Remote: Bug!\n");
      if (auth_status == 1)  fprintf(stderr, "SamsungTV Remote: Access Denied\n");
      if (auth_status == 2)  fprintf(stderr, "SamsungTV Remote: Waiting On User\n");
      if (auth_status == 3)  fprintf(stderr, "SamsungTV Remote: Time Out\n");
    }
    
    close(net_socket);
    freeaddrinfo(res);
    return 0;
}

Re: Remote Control CLI (included c source)

Posted: Fri Apr 12, 2013 6:57 am
by juusso
Thanks! You should add some usage examples, key format and so on...

Edit:
Checked on D series and can confirm it does what it supposed to do. Compiled for arm and x686 (debian vmware image).

Code: Select all

./cli
SamsungTV Remote Control CLI v0.01 April 2013 TRiXWooD
usage: STVCLI IP KEY
       STVCLI IP -T TEXT

LS-GL:/TV# ./cli 192.168.1.202 hello
SamsungTV Remote: Waiting On User
After confirmation of new network remote on TV, cli works as expected!

Code: Select all

 ./cli 192.168.1.202 KEY_MUTE
Key codes are available on wiki. And what is fun, we can send 3SPEED and FACTORY keys as well. :)

I think should work on C/D/E series TV`s. And maybe F? And another idea - is it possible to get result of executed command, i mean response from TV - executed or not. Does it send any thing back?

Re: Remote Control CLI (included c source)

Posted: Fri Apr 12, 2013 6:51 pm
by TRiXWooD
I could not sleep, so here some extensions on the previous source... now you can send "tha bubbles" (soap sms,call,schedule) to your tv...

It should probably work in D/E/... but I only have a little c ;-) (*edit
viewtopic.php?f=49&t=4866#p36105 says no for soap on E en D7/D8 :roll: remote part should still work though...)
I still have to write the error handling for the network code, but it does give a result back. Only good result is no result :P.
Repeated keypressed for example are detected and send back (but not displayed).
The only thing that does not give a result back is the TEXT part, the TV does not send anything back.
DisplayType Maximum in a soap request does nothing for me... anybody any experience with soap?
Funny to see that you got a user waiting... it was impossible for me to generate that on my little c.
Still missing input checking/filtering.

Ow. I added some examples. A nice touch is forwarding the soap port and the remote port on my internet router and created a script that popup message and auto closes them after 3 seconds ;-) Now I really can annoy my sister when see is watching her favorite "soap" even when I am not at home :mrgreen:

Still looking for an option to display an image on the screen (overlay) using a c-series valdeac, anybody any luck?, instead of the message box... that would be sweet. I did not found a frambuffer on my c6710... :x
also still looking for a good nmbd file that will work... or a way how to create one...

Some links:

http://wiki.samygo.tv/index.php5/Key_codes
http://wiki.samygo.tv/index.php5/Samsun ... l_protocol
SpoilerShow

Code: Select all

/*
 *   SamsungTV Remote C++ Command Line Interface v0.02 April 2013 TRiXWooD (cris.wood.org -AD- gmail.com)
 *
 *   Network Error Handling (Mostly Missing)
 *   Key &| Text Input Checking some chars will result in disabling the tv's remote part
 *
 *   v0.00 Prototype
 *   v0.01 Remote Working
 *   v0.02 SOAP Message Working
 *
 *   modified base64 (Base64EncodeDecode.c) from Sam Ernest Kumar 
 *   part code/research from various places/people on the samygo forum
 */

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>


int samsungtv_base64encodeblock(char *input, char *output, int oplen){
    int rc = 0, iplen = 0;
    char encodedstr[5] = "";
    char encodingtabe[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    iplen = strlen(input);
    encodedstr[0] = encodingtabe[ input[0] >> 2 ];
    encodedstr[1] = encodingtabe[ ((input[0] & 0x03) << 4) | ((input[1] & 0xf0) >> 4) ];
    encodedstr[2] = (iplen > 1 ? encodingtabe[ ((input[1] & 0x0f) << 2) | ((input[2] & 0xc0) >> 6) ] : '=');
    encodedstr[3] = (iplen > 2 ? encodingtabe[ input[2] & 0x3f ] : '=');
    strncat(output, encodedstr, oplen-strlen(output));    
    return rc;
}

int samsungtv_base64encode(char *input, char *output, int oplen){
    int rc = 0;
    int index = 0, ipindex = 0, iplen = 0;
    char encoderinput[4] = "";
    iplen = strlen(input);
    while(ipindex < iplen){
        for(index = 0; index < 3; index++){
            if(ipindex < iplen){
                encoderinput[index] = input[ipindex];
            }else{
                encoderinput[index] = 0;
            }
            ipindex++;
        }
        rc = samsungtv_base64encodeblock(encoderinput, output, oplen);
    }
    return rc;
}

int samsungtv_response(int net_socket) {
  unsigned char message[256];
  memset (message,0x00,256);
  int i = 3;
  recv(net_socket,message,3,0);
  recv(net_socket,message+i,message[1],0);
  i += message[1];
  recv(net_socket,message+i,2,0);
  i += 2;
  unsigned char response = message[i-2];
  recv(net_socket,message+i,response,0);
  i += response;
  if (message[i-4] == 0x00 && message[i-3] == 0x00 && message[i-2] == 0x00 && message[i-1] == 0x00)
      if (message[0] == 0x01) return 4;                       // success repeat keystroke...
      else return 0;                                          // success
  if (message[i-response] == 0x65) return 3;                  // timeoutt....
  if (message[i-4] == 0x64 && message[i-2] == 0x00) return 1; // access denied...
  if (message[i-4] == 0x64 && message[i-2] == 0x01) return 0; // success
  if (message[i-response] == 0x0A) return 2;                  // waiting for user...
  return -1;                                                  // bug!
}

int samsungtv_setlength(unsigned char message[], unsigned int length) {
    message[0] = (unsigned char) (length & 0xFF);
    message[1] = (unsigned char) ((length >> 8) & 0xFF);
}

int samsungtv_setstring(unsigned char message[],unsigned char string[],int base64) {
    unsigned char s[512];
    memset (s,0x00,512);
    if (base64 == 1) samsungtv_base64encode(string,s,strlen(string)*2);
    else strncpy(s,string,strlen(string));
    samsungtv_setlength(message,strlen(s));
    strncpy(message+2,s,strlen(s));
    return strlen(s)+2;
}

enum modes {eKey, eText, eSMS, eCall, eSchedule, eAuth, eUnknown};

int samsungtv_message(unsigned char string[], int net_socket,int type) {
    unsigned char remote[] = "SamsungTVRemote";
    unsigned char message[1024];
    memset (message,0x00,1024);
    unsigned int s = samsungtv_setstring(message+1,"iphone.iapp.samsung",0) + 1;
    unsigned int i = s + 4 + (type==eKey?1:0);
    i += samsungtv_setstring(message+i,string,1);
    if (type == eAuth) {
        message[s+2] = 0x64;
        i += samsungtv_setstring(message+i,remote,1);
        i += samsungtv_setstring(message+i,remote,1);
    }
    if (type == eText) {
      message[0] = 0x01;
      message[s+2] = 0x01;
    }
    samsungtv_setlength(message+s,i-s-2);
    send(net_socket,message, i, 0);
    return (type==eText?0:samsungtv_response(net_socket));
}

int samsungtv_authenticate(unsigned char ip[], int net_socket) { return samsungtv_message(ip,net_socket,eAuth); }
int samsungtv_key(unsigned char key[], int net_socket) { return samsungtv_message(key,net_socket,eKey); }
int samsungtv_text(unsigned char text[], int net_socket) { return samsungtv_message(text,net_socket,eText); }

int samsungtv_sms(char ip[], int net_socket, char date[], char time[], char from[], char fromnumber[], char to[],
                  char tonumber[], char message[]) {
   char request[3072];
    sprintf( request,"<Category>SMS</Category>"
           "<DisplayType>Maximum</DisplayType>"
           "<ReceiveTime>"
           "<Date>%s</Date>"
           "<Time>%s</Time>"
           "</ReceiveTime>"
           "<Receiver>"
           "<Number>%s</Number>"
           "<Name>%s</Name>"
           "</Receiver>"
           "<Sender>"
           "<Number>%s</Number>"
           "<Name>%s</Name>"
           "</Sender>"
           "<Body>%s</Body>",date,time,tonumber,to,fromnumber,from,message);
    return samsungtv_soap(ip,net_socket,request);
}

int samsungtv_schedule(char ip[], int net_socket,  char subject[], char startdate[], char starttime[], char enddate[], char endtime[], char location[], char owner[], char number[], char message[]) {
char request[3072];
 sprintf(  request,"<Category>Schedule Reminder</Category>"
 "<DisplayType>Maximum</DisplayType>"
 "<StartTime>"
 "<Date>%s</Date>"
 "<Time>%s</Time>"
 "</StartTime>"
 "<Owner>"
 "<Number>%s</Number>"
 "<Name>%s</Name>"
 "</Owner>"
 "<Subject>%s</Subject>"
 "<EndTime>"
 "<Date>%s</Date>"
 "<Time>%s</Time>"
 "</EndTime>"
 "<Location>%s</Location>"
 "<Body>%s</Body>",startdate,starttime,number,owner,subject,enddate,endtime,location,message);
  return samsungtv_soap(ip,net_socket,request);

}

int samsungtv_call(char ip[], int net_socket, char date[], char time[], char from[], char fromnumber[], char to[] , char tonumber[]) {
    
    char request[3072];
    sprintf( request,"<Category>Incoming Call</Category>"
            "<DisplayType>Maximum</DisplayType>"
            "<CallTime>"
            "<Date>%s</Date>"
            "<Time>%s</Time>"
            "</CallTime>"
            "<Callee>"
            "<Number>%s</Number>"
            "<Name>%s</Name>"
            "</Callee>"
            "<Caller>"
            "<Number>%s</Number>"
            "<Name>%s</Name>"
            "</Caller>",date,time,tonumber,to,fromnumber,from);

    return samsungtv_soap(ip,net_socket,request);
}

int samsungtv_soap(unsigned char ip[], int net_socket,char requestbody[]) {
    
    char request[3072];
    char buffer[4096];
    
    strcpy( request,
           "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
           "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
           "<s:Body>"
           "      <u:AddMessage xmlns:u=\"urn:samsung.com:service:MessageBoxService:1\">"
           "         <MessageType>text/xml</MessageType>"
           "         <MessageID>anything</MessageID>"
           "<Message>");
    
    strcat(request,requestbody);
    strcat(request,
           "</Message>"
           "      </u:AddMessage>"
           "   </s:Body>"
           "</s:Envelope>" );

   sprintf( buffer,
        "POST /PMR/control/MessageBoxService HTTP/1.0\r\n"
        "Content-Type: text/xml; charset=\"utf-8\"\r\n"
        "HOST: %s\r\n"
        "Content-Length: %d\r\n"
        "SOAPACTION: \"uuid:samsung.com:service:MessageBoxService:1#AddMessage\"\r\n"
        "Connection: close\r\n"
        "\r\n", ip, strlen( request));
    strcat( buffer, request );
    
    int numbytes;
    if((numbytes = send(net_socket, buffer, strlen( buffer ), 0)) == -1) { }    
    if((numbytes = recv(net_socket, buffer, 10000, 0)) == -1) { }
}

int main(int argc, char *argv[]) {
    
    struct addrinfo hints, *res, *p;
    int net_status, net_socket;
      enum modes mode = eUnknown;
    
    if (argc > 2) {
        if (strcmp(argv[2],"-TEXT") == 0) mode = eText;
        if (strcmp(argv[2],"-KEY") == 0) mode = eKey;
        if (strcmp(argv[2],"-SMS") == 0) mode = eSMS;
        if (strcmp(argv[2],"-CALL") == 0) mode = eCall;
        if (strcmp(argv[2],"-SCHEDULE") == 0) mode = eSchedule;
        
    }
    
    if (argc < 4 || mode == eUnknown ||
        
        !(mode == eText && argc == 4) &&
        !(mode == eKey && argc == 4) &&
        !(mode == eSMS && argc == 10) &&
        !(mode == eCall && argc == 9) &&
        !(mode == eSchedule && argc == 12) 
        
        ) {
        printf("SamsungTV Remote Control CLI v0.02 April 2013 TRiXWooD\n");
        printf("usage: STVCLI IP -KEY      KEY\n");
        printf("       STVCLI IP -TEXT     TEXT\n");
        printf("       STVCLI IP -SMS      DATE TIME FROM NUMBER TO NUMBER MESSAGE\n");
        printf("       STVCLI IP -CALL     DATE TIME FROM NUMBER TO NUMBER\n");
        printf("       STVCLI IP -SCHEDULE SUBJECT STARTDATE STARTTIME ENDDATE ENDTIME LOCATION OWNER NUMBER MESSAGE\n\n");
        printf("examples: STVCLI 192.168.1.11 -KEY KEY_VOLUP\n             --Simulates Press Volume Up\n");
        printf("          STVCLI 192.168.1.11 -TEXT \"Colour Haze\"\n             --Sends Text To Youtube...\n");
        printf("          STVCLI 192.168.1.11 -SMS 2013-6-24 \"7:01:01 PM\" Cris +555-4323 Me +555-2343 \"Get Off The Couch\"\n             --Show Incomming SMS...\n");
        printf("          STVCLI 192.168.1.11 -CALL 23:06:01 Cris +555-4323 \"\" \"\"\n             --Show Incomming Call (skips input with empty strings)...\n\n\n");
        printf("exmaple script for displaying popup message\n(hint forward ports 52235 & 55000 on your internet router so you can reach your tv from anywhere)\n\nusage popup.sh 10.0.0.2 \"Pop Says The Message on C6710\"\n\nSTVCLI $1 -SMS \"\" \"\" \"\" \"\" \"\" \"\" $2\nSLEEP 0.3\nSTVCLI $1 -KEY KEY_ENTER\nSLEEP 3\nSTVCLI $1 -KEY KEY_ENTER\n");
       return 1;
    }
    
    char port[] = "55000";
    if (mode != eKey && mode != eText) strcpy(port,"52235");
    
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
    hints.ai_socktype = SOCK_STREAM;
        if ((net_status = getaddrinfo(argv[1],port, &hints, &res)) != 0) {
        fprintf(stderr, "SamsungTV Remote Control: Connection Failure: (%s)\n", gai_strerror(net_status));
        return 2;
    }
    net_socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if ((net_status = connect(net_socket, res->ai_addr, res->ai_addrlen)) != 0) {
        fprintf(stderr, "SamsungTV Remote Control: Connected Failure (%s)\n", gai_strerror(net_status));
        return 2;
    }
    
    if (mode == eKey || mode == eText) {
      int response,auth_status = samsungtv_authenticate(argv[1],net_socket);
      if (auth_status == 0) {
        if (mode == eText) response = samsungtv_text(argv[3],net_socket);
        else response = samsungtv_key(argv[3],net_socket);
        if (response != 0 && response != 4) fprintf(stderr, "SamsungTV Remote Control: Bug!\n");
      }
      else
      { if (auth_status == -1) fprintf(stderr, "SamsungTV Remote Control: Bug!\n");
        if (auth_status == 1)  fprintf(stderr, "SamsungTV Remote Control: Access Denied\n");
        if (auth_status == 2)  fprintf(stderr, "SamsungTV Remote Control: Waiting On User\n");
        if (auth_status == 3)  fprintf(stderr, "SamsungTV Remote Control: Time Out\n");
       }
    }
    else {
       if (mode == eSMS) samsungtv_sms(argv[1],net_socket,argv[3],argv[4],argv[5],argv[6],argv[7],argv[8],argv[9]);
       if (mode == eCall) samsungtv_call(argv[1],net_socket,argv[3],argv[4],argv[5],argv[6],argv[7],argv[8]);
       if (mode == eSchedule) samsungtv_schedule(argv[1],net_socket,argv[3],argv[4],argv[5],argv[6],argv[7],argv[8],argv[9],argv[10],argv[11]);
    }
    close(net_socket);
    freeaddrinfo(res);
    return 0;
}

/*
 KEY_0
 KEY_1
 KEY_2
 KEY_3
 KEY_4
 KEY_5
 KEY_6
 KEY_7
 KEY_8
 KEY_9
 KEY_11
 KEY_12
 KEY_3SPEED
 KEY_4_3
 KEY_16_9
 KEY_AD
 KEY_ADDDEL
 KEY_ALT_MHP
 KEY_ANGLE
 KEY_ANTENA
 KEY_ANYNET
 KEY_ANYVIEW
 KEY_APP_LIST
 KEY_ASPECT
 KEY_AUTO_ARC_ANTENNA_AIR
 KEY_AUTO_ARC_ANTENNA_CABLE
 KEY_AUTO_ARC_ANTENNA_SATELLITE
 KEY_AUTO_ARC_ANYNET_AUTO_START
 KEY_AUTO_ARC_ANYNET_MODE_OK
 KEY_AUTO_ARC_AUTOCOLOR_FAIL
 KEY_AUTO_ARC_AUTOCOLOR_SUCCESS
 KEY_AUTO_ARC_CAPTION_ENG
 KEY_AUTO_ARC_CAPTION_KOR
 KEY_AUTO_ARC_CAPTION_OFF
 KEY_AUTO_ARC_CAPTION_ON
 KEY_AUTO_ARC_C_FORCE_AGING
 KEY_AUTO_ARC_JACK_IDENT
 KEY_AUTO_ARC_LNA_OFF
 KEY_AUTO_ARC_LNA_ON
 KEY_AUTO_ARC_PIP_CH_CHANGE
 KEY_AUTO_ARC_PIP_DOUBLE
 KEY_AUTO_ARC_PIP_LARGE
 KEY_AUTO_ARC_PIP_LEFT_BOTTOM
 KEY_AUTO_ARC_PIP_LEFT_TOP
 KEY_AUTO_ARC_PIP_RIGHT_BOTTOM
 KEY_AUTO_ARC_PIP_RIGHT_TOP
 KEY_AUTO_ARC_PIP_SMALL
 KEY_AUTO_ARC_PIP_SOURCE_CHANGE
 KEY_AUTO_ARC_PIP_WIDE
 KEY_AUTO_ARC_RESET
 KEY_AUTO_ARC_USBJACK_INSPECT
 KEY_AUTO_FORMAT
 KEY_AUTO_PROGRAM
 KEY_AV1
 KEY_AV2
 KEY_AV3
 KEY_BACK_MHP
 KEY_BOOKMARK
 KEY_CALLER_ID
 KEY_CAPTION
 KEY_CATV_MODE
 KEY_CHDOWN
 KEY_CHUP
 KEY_CH_LIST
 KEY_CLEAR
 KEY_CLOCK_DISPLAY
 KEY_COMPONENT1
 KEY_COMPONENT2
 KEY_CONTENTS
 KEY_CONVERGENCE
 KEY_CONVERT_AUDIO_MAINSUB
 KEY_CUSTOM
 KEY_CYAN
 KEY_DEVICE_CONNECT
 KEY_DISC_MENU
 KEY_DMA
 KEY_DNET
 KEY_DNIe
 KEY_DNSe
 KEY_DOOR
 KEY_DOWN
 KEY_DSS_MODE
 KEY_DTV
 KEY_DTV_LINK
 KEY_DTV_SIGNAL
 KEY_DVD_MODE
 KEY_DVI
 KEY_DVR
 KEY_DVR_MENU
 KEY_DYNAMIC
 KEY_ENTER
 KEY_ENTERTAINMENT
 KEY_ESAVING
 KEY_EXIT
 KEY_EXT1
 KEY_EXT2
 KEY_EXT3
 KEY_EXT4
 KEY_EXT5
 KEY_EXT6
 KEY_EXT7
 KEY_EXT8
 KEY_EXT9
 KEY_EXT10
 KEY_EXT11
 KEY_EXT12
 KEY_EXT13
 KEY_EXT14
 KEY_EXT15
 KEY_EXT16
 KEY_EXT17
 KEY_EXT18
 KEY_EXT19
 KEY_EXT20
 KEY_EXT21
 KEY_EXT22
 KEY_EXT23
 KEY_EXT24
 KEY_EXT25
 KEY_EXT26
 KEY_EXT27
 KEY_EXT28
 KEY_EXT29
 KEY_EXT30
 KEY_EXT31
 KEY_EXT32
 KEY_EXT33
 KEY_EXT34
 KEY_EXT35
 KEY_EXT36
 KEY_EXT37
 KEY_EXT38
 KEY_EXT39
 KEY_EXT40
 KEY_EXT41
 KEY_FACTORY
 KEY_FAVCH
 KEY_FF
 KEY_FF_
 KEY_FM_RADIO
 KEY_GAME
 KEY_GREEN
 KEY_GUIDE
 KEY_HDMI
 KEY_HDMI1
 KEY_HDMI2
 KEY_HDMI3
 KEY_HDMI4
 KEY_HELP
 KEY_HOME
 KEY_ID_INPUT
 KEY_ID_SETUP
 KEY_INFO
 KEY_INSTANT_REPLAY
 KEY_LEFT
 KEY_LINK
 KEY_LIVE
 KEY_MAGIC_BRIGHT
 KEY_MAGIC_CHANNEL
 KEY_MDC
 KEY_MENU
 KEY_MIC
 KEY_MORE
 KEY_MOVIE1
 KEY_MS
 KEY_MTS
 KEY_MUTE
 KEY_NINE_SEPERATE
 KEY_OPEN
 KEY_PANNEL_CHDOWN
 KEY_PANNEL_CHUP
 KEY_PANNEL_ENTER
 KEY_PANNEL_MENU
 KEY_PANNEL_POWER
 KEY_PANNEL_SOURCE
 KEY_PANNEL_VOLDOW
 KEY_PANNEL_VOLUP
 KEY_PANORAMA
 KEY_PAUSE
 KEY_PCMODE
 KEY_PERPECT_FOCUS
 KEY_PICTURE_SIZE
 KEY_PIP_CHDOWN
 KEY_PIP_CHUP
 KEY_PIP_ONOFF
 KEY_PIP_SCAN
 KEY_PIP_SIZE
 KEY_PIP_SWAP
 KEY_PLAY
 KEY_PLUS100
 KEY_PMODE
 KEY_POWER
 KEY_POWEROFF
 KEY_POWERON
 KEY_PRECH
 KEY_PRINT
 KEY_PROGRAM
 KEY_QUICK_REPLAY
 KEY_REC
 KEY_RED
 KEY_REPEAT
 KEY_RESERVED1
 KEY_RETURN
 KEY_REWIND
 KEY_REWIND_
 KEY_RIGHT
 KEY_RSS
 KEY_RSURF
 KEY_SCALE
 KEY_SEFFECT
 KEY_SETUP_CLOCK_TIMER
 KEY_SLEEP
 KEY_SOUND_MODE
 KEY_SOURCE
 KEY_SRS
 KEY_STANDARD
 KEY_STB_MODE
 KEY_STILL_PICTURE
 KEY_STOP
 KEY_SUB_TITLE
 KEY_SVIDEO1
 KEY_SVIDEO2
 KEY_SVIDEO3
 KEY_TOOLS
 KEY_TOPMENU
 KEY_TTX_MIX
 KEY_TTX_SUBFACE
 KEY_TURBO
 KEY_TV
 KEY_TV_MODE
 KEY_UP
 KEY_VCHIP
 KEY_VCR_MODE
 KEY_VOLDOWN
 KEY_VOLUP
 KEY_WHEEL_LEFT
 KEY_WHEEL_RIGHT
 KEY_W_LINK
 KEY_YELLOW
 KEY_ZOOM1
 KEY_ZOOmessage
 KEY_ZOOM_IN
 KEY_ZOOM_MOVE
 KEY_ZOOM_OUT
 */

/*  Future!!!!  GetVolume/GetMute...  && Trying to Play a avi.... 
POST /upnp/control/RenderingControl1 HTTP/1.1
Host: 192.168.0.10:52235
SOAPAction: "urn:schemas-upnp-org:service:RenderingControl:1#SetMute"
Accept-Language: LC-ctype=en-us;q=1, LC-ctype=en;q=0.5
Content-Type: text/xml; charset=utf-8
Content-Length: 335

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body><u:SetMute xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1">
<InstanceID>0</InstanceID>
<Channel>Master</Channel>
<DesiredMute>0</DesiredMute></u:SetMute>
</s:Body>
</s:Envelope>
 
 POST /upnp/control/AVTransport1 HTTP/1.1
 SOAPACTION: urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI
 Connection: close
 Content-Length: 619
 Content-Type: text/xml
 Host: 192.168.1.51:52235
 User-Agent: HttpSamyGO/1.1
 
 <?xml version='1.0' encoding='UTF-8' standalone='no' ?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><CurrentURI>http://75.101.165.227:8080/app/iLJy+VD9xyYqv5jtERGBijAeiqUmYWqCFzy4Li6gM0uMzI8pYoRWTxqp+UxEy14ibHGOrLpqJTkjI+WE6Q6lbQ6e2+1X96ToH8lGCv0f4f88M0jxU6S6z4SwC8KOCoMhscRxjOiy4CJVzNNeCGQxpw==.mp4</CurrentURI><CurrentURIMetaData><DIDL-Lite></DIDL-Lite></CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>
 
 */

Re: Remote Control CLI (included c source)

Posted: Sun Apr 14, 2013 1:07 am
by pohybel
It's great! I've just compiled it for OpenWrt ar71xx ruters. Now I'm able to turn off my TV remotely ;)

Briefly tested with D-series (UE40D6750) and it works - of course without "-T" option

Re: Remote Control CLI (included c source)

Posted: Sun Sep 14, 2014 4:16 pm
by zoelechat
UP :mrgreen:

If anybody is interested, here is a version compiled for Windows (uses included cygwin1.dll)
Tested on WinXP 32bit/Win7 64bit with ES series TV, should probably work with any version/model (up to F series).

Code: Select all

SamsungTV Remote Control CLI v0.01 April 2013 TRiXWooD
usage: STVCLI IP KEY
       STVCLI IP -T TEXT

edit (much later!):
Added mingw32 much lighter native win32 build. No dll required.
+MacOS build

Re: Remote Control CLI (included c source)

Posted: Sun Jan 31, 2016 4:27 pm
by thomasfl
Nice work.

Just FYI (and to make it easier to google) -- the ARM executable also works to control a Samsung TV from a Raspberry Pi running OpenElec.

Re: Remote Control CLI (included c source)

Posted: Sun Oct 23, 2016 6:35 pm
by madrian
Guys, the cli app is working perfectly, but how do I turn on the TV?

If it is turned off, I can't ping my TV and commands are not working:

@raspberrypi:~/temp $ ./cli 192.168.1.29 KEY_POWERON
SamsungTV Remote: Connected Failure (Bad value for ai_flags)
@raspberrypi:~/temp $ ./cli 192.168.1.29 KEY_POWER
SamsungTV Remote: Connected Failure (Bad value for ai_flags)

Re: Remote Control CLI (included c source)

Posted: Sun Oct 23, 2016 7:15 pm
by sectroyer
connect rpi via hdmi and use cec :)

Re: Remote Control CLI (included c source)

Posted: Sun Oct 23, 2016 7:40 pm
by madrian
If I connect rPi via CEC, but my primary source is on another HDMI port - It will work? I do not want to automatically switch to rPi, when TV turns on.

Re: Remote Control CLI (included c source)

Posted: Sun Oct 23, 2016 8:23 pm
by madrian
So I installed cic-client, and now I am able to turn on my TV via:

echo on 0 | cec-client -s -d 1

...but I am unable to turn off. Any ideas how to get this working? :)