Announcement

Collapse
No announcement yet.

Slingbox/Slingplayer plugin?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Slingbox/Slingplayer plugin?

    Has anyone thought of coding one? (I would do it if I weren't a dimwit )
    My Grandma & Her Friends on Their Spring Vacation

  • #2
    I wish some1 would make one also. I mean you can add it as an app, but it sucks to have it open up in its own external window.
    Nirwana Project, the Android/Win 7 hybrid system!

    1X Ainol Novo Flame Tab
    4X MK808b
    3x Perixx Touchpads
    3x 7 inch Screens
    1X 7 inch motorized Screen
    1x Win 7 PC

    Comment


    • #3
      Originally posted by HiJackZX1 View Post
      I wish some1 would make one also. I mean you can add it as an app, but it sucks to have it open up in its own external window.
      Plus it would be nice to have nice big finger-friendly buttons as well.
      My Grandma & Her Friends on Their Spring Vacation

      Comment


      • #4
        Originally posted by Nola111 View Post
        Plus it would be nice to have nice big finger-friendly buttons as well.
        Your right about that. Sling Player does have a UMPC Skin, but even with that its still hard to press buttons. If you want my opinion, all you clever programmers, is do not base your plugin on the Sling Player for PC, but base it on the Sling Player for mobile phones. It has a standard remote, unlike the PC version that uses a direct picture of the remote for that device. The mobile version has a generic remote, which could easily be made to have big buttons for Car PC users.
        Nirwana Project, the Android/Win 7 hybrid system!

        1X Ainol Novo Flame Tab
        4X MK808b
        3x Perixx Touchpads
        3x 7 inch Screens
        1X 7 inch motorized Screen
        1x Win 7 PC

        Comment


        • #5
          I did not make a Plugin, but I just added the Slingplayer as an Application. I have it set to full screen mode and have it set to auto connect to last Slingbox and it works great.

          Only problem I have is I have a wireless remote but the number buttons do not press numbers on the PC. Anyone know how I can edit the settings on the remote or in windows so when I press 1 on the remote it types in the number 1.

          Here is the remote I have.

          http://store.mo-co-so.com/wireless-i...ouse-p-77.html
          Scott
          SatelliteGuys.US

          Comment


          • #6
            Originally posted by satelliteguys View Post
            I did not make a Plugin, but I just added the Slingplayer as an Application. I have it set to full screen mode and have it set to auto connect to last Slingbox and it works great.

            Only problem I have is I have a wireless remote but the number buttons do not press numbers on the PC. Anyone know how I can edit the settings on the remote or in windows so when I press 1 on the remote it types in the number 1.

            Here is the remote I have.

            http://store.mo-co-so.com/wireless-i...ouse-p-77.html
            Is the Sling Player embeded inside Centrafuse though? Thats why we want a plug-in. I hate having to close out Sling Player then hitting X on the screen CF pops up also.
            Nirwana Project, the Android/Win 7 hybrid system!

            1X Ainol Novo Flame Tab
            4X MK808b
            3x Perixx Touchpads
            3x 7 inch Screens
            1X 7 inch motorized Screen
            1x Win 7 PC

            Comment


            • #7
              Ok, I'm willing to pay someone to develop this plugin. PM me if you're interested and able.
              My Grandma & Her Friends on Their Spring Vacation

              Comment


              • #8
                Originally posted by Nola111 View Post
                Ok, I'm willing to pay someone to develop this plugin. PM me if you're interested and able.
                x2. I would be willing to contribute to this as well.

                Comment


                • #9
                  I am also willing to pay too. Im worried though that creating a plugin now would be pointless. Sling Box is getting ready to launch a new player, if they havent already done so. I remember reading about a tool for CF that can grab and list the window information so you can embed programs into CF. Does that program still exist? I have a few other programs I would like to try (Gens Sega Emulator) and a few more. I dont know how to manually go about getting window info.
                  Nirwana Project, the Android/Win 7 hybrid system!

                  1X Ainol Novo Flame Tab
                  4X MK808b
                  3x Perixx Touchpads
                  3x 7 inch Screens
                  1X 7 inch motorized Screen
                  1x Win 7 PC

                  Comment


                  • #10
                    I would be ok with embedding with the exception of channel number buttons and channel preset buttons. Those are too small in the player software. The play/stop button is nice and big and finger-friendly so that's ok.

                    If they are coming out with a new one, even better, we'd base the plugin off the latest, no? I'll bet their SDK won't change much from the current version anyway.
                    My Grandma & Her Friends on Their Spring Vacation

                    Comment


                    • #11
                      I have said this in previous posts, but i think someone should somehow make a plugin based on the touchscreen PPC version of the player. It is very generic and easy to use. All we would have to do is make the button interface bigger.....
                      Nirwana Project, the Android/Win 7 hybrid system!

                      1X Ainol Novo Flame Tab
                      4X MK808b
                      3x Perixx Touchpads
                      3x 7 inch Screens
                      1X 7 inch motorized Screen
                      1x Win 7 PC

                      Comment


                      • #12
                        Ok, I have been researching a bit, and I found a plugin that you put into VLC Player to stream Slingbox on VLC without having to use Sling Player. The person that made it, gave all the files to do it, maybe someone can adapt it to CF?

                        I have attached a RAR file that has all the instructions to set it up in VLC, but there is also a txt pad that has how he made the .dll file..... Maybe someone can adapt it?

                        Code:
                        /*****************************************************************************
                         * slingbox.c: HTTP input module
                         *****************************************************************************
                         *
                         * Authors: ChecksumCoder <[email protected]
                         *
                         * This is a modification (maybe a very big but...) of http.c then ...
                         * 
                         *****************************************************************************
                         * http.c: HTTP input module
                         *****************************************************************************
                         * Copyright (C) 2001-2005 the VideoLAN team
                         * $Id: http.c 15169 2006-04-11 09:27:46Z zorglub $
                         *
                         * Authors: Laurent Aimar <[email protected]>
                         *          Christophe Massiot <[email protected]>
                         *          Rémi Denis-Courmont <rem # videolan.org>
                         *
                         * This program is free software; you can redistribute it and/or modify
                         * it under the terms of the GNU General Public License as published by
                         * the Free Software Foundation; either version 2 of the License, or
                         * (at your option) any later version.
                         *
                         * This program is distributed in the hope that it will be useful,
                         * but WITHOUT ANY WARRANTY; without even the implied warranty of
                         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                         * GNU General Public License for more details.
                         *
                         * You should have received a copy of the GNU General Public License
                         * along with this program; if not, write to the Free Software
                         * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
                         *****************************************************************************/
                        
                        /*****************************************************************************
                         * Preamble
                         *****************************************************************************/
                        #include <stdlib.h>
                        
                        #include <vlc/vlc.h>
                        #include <vlc/input.h>
                        
                        #include "vlc_interaction.h"
                        #include "network.h"
                        #include "vlc_url.h"
                        #include "vlc_tls.h"
                        #include "vlc_keys.h"
                        #include "vlc_osd.h"
                        
                        
                        #define LOG_COMM
                        
                        /*****************************************************************************
                         * Module descriptor
                         *****************************************************************************/
                        static int  Open ( vlc_object_t * );
                        static void Close( vlc_object_t * );
                        static int Read( access_t *p_access, uint8_t *p_buffer, int i_len );
                        static int ReadCommand( vlc_object_t *p_this );
                        static int KeyHandler (vlc_object_t *obj, char const *varname, vlc_value_t oldval, vlc_value_t newval, void *data);
                        
                        
                        int m_strnicmp(const char *a,const char *b, int s)
                        {
                        	int i;
                        	for (  i = 0 ; i < s && *a && *b ; i ++ ) {
                        		if ( *a != *b ) return *a > *b ? 1:-1;
                        		a++;
                        		b++;
                        	}
                        	return 0;
                        }
                        
                        
                        vlc_module_begin();
                            set_description( _("Slingbox") );
                            set_capability( "access2", 0 );
                            set_shortname( _( "Slingbox" ) );
                        
                            set_category( CAT_INPUT );
                            set_subcategory( SUBCAT_INPUT_ACCESS );
                        
                        	set_section( N_("Control") , NULL );
                        	add_integer( "slingbox-channel", 0,NULL, N_("Channel"), N_( "Channel (0 = kept last channel)" ), VLC_FALSE );
                        	add_integer( "slingbox-input", 0,NULL, N_("Input"), N_( "Channel (-1 = kept last input)" ), VLC_FALSE );
                        
                        	set_section( N_("Connection") , NULL );
                            add_string( "slingbox-user", "VLC" , NULL, N_("User name") , N_("Not used") , VLC_TRUE );
                            add_string( "slingbox-password", "" , NULL, N_("Password") , N_("Password used to log on Slingbox") , VLC_FALSE );
                        	add_bool  ( "slingbox-admin",VLC_TRUE , NULL,N_("Admin"), N_("Log as administrator") , VLC_FALSE );
                            add_string( "slingbox-adrs", "192.168.1.237" , NULL, N_("Adress") , N_("Default adress if not specified") , VLC_TRUE );
                        	add_integer( "slingbox-port", 5001,NULL, N_("Port"), N_( "Default port if not specified" ), VLC_TRUE );
                        	add_integer( "slingbox-caching", 8 * DEFAULT_PTS_DELAY / 1000, NULL, N_("Caching value in ms"), N_( "Caching value for slingbox streams. This value should be set in milliseconds." ), VLC_TRUE );
                        
                        
                        
                        	set_section( N_("Video") , NULL );
                            add_string( "slingbox-resolution", "1" , NULL, "Resolution", "Video resolution", VLC_TRUE );
                        	static char *resolution_list[] = {         "8",             "2",             "4",            "9",            "11",            "1",             "7",             "3",            "6",            "5"};
                        	static char *resolution_list_text[] = { N_("128 X 96"),  N_("160 X 120"), N_("176 X 120"),N_("224 X 176"),N_("256 X 192"), N_("320 X 240"), N_("352 X 480"), N_("352 X 240"),N_("640 X 240"),N_("640 X 480") };
                        	change_string_list( resolution_list, resolution_list_text, 0 );
                        	add_integer_with_range( "slingbox-videobitrate", 1000, 50, 8000, NULL,   N_("Video Bitrate"), N_("Bitrate of the Video stream in Kbps") , VLC_TRUE );
                            add_string( "slingbox-framerate", "30" , NULL, "Framerate", "Video framerate", VLC_TRUE );
                        	static char *framerate_list[] = { "1","6","10","15","20","30"};
                        	static char *framerate_list_text[] = { N_("1 f/s"), N_("6 f/s"), N_("10 f/s"),N_("15 f/s"), N_("20 f/s"),N_("30 f/s") };
                        	change_string_list( framerate_list, framerate_list_text, 0 );
                        	add_integer_with_range( "slingbox-videosmoothness", 32, 1, 64, NULL,N_("Video smoothness"), N_("high val = sharper") , VLC_TRUE );
                        	add_integer_with_range( "slingbox-iframe", 10, 1, 30, NULL,N_("I-Frame"), N_("I-Frame interval in seconds") , VLC_TRUE );
                        	add_string( "slingbox-audio", "96" , NULL, "Audio bitrate", "Bitrate of the audio in Kbps", VLC_TRUE );
                        	static char *audiobitrate_list[] = { "16","20","32","40","48","64","96"};
                        	static char *audiobitrate_list_text[] = { N_("16 Kbps"), N_("20 Kbps"), N_("32 Kbps"),N_("40 Kbps"), N_("48 Kbps"),N_("64 Kbps"),N_("96 Kbps") };
                        	change_string_list( audiobitrate_list, audiobitrate_list_text, 0 );
                        
                        
                        	set_section( N_("Log") , NULL );
                        	add_bool  ( "slingbox-log",VLC_FALSE , NULL,N_("Log"), N_("Log communiction in Message") , VLC_FALSE );
                        
                        	add_shortcut( "slingbox" );
                            add_shortcut( "sling" );
                        
                            set_callbacks( Open, Close );
                        	
                        vlc_module_end();
                        
                        
                        /*****************************************************************************
                         * Local prototypes
                         *****************************************************************************/
                        struct access_sys_t
                        {
                            int fdCommand,fd;
                            vlc_bool_t VideoSupplementChange; 
                            v_socket_t    *p_vs;
                            v_socket_t    *p_vsCommand;
                        
                        
                            /* From uri */
                            vlc_url_t url;
                            char   *psz_slingbox;
                        
                        
                        	time_t endtime;
                        
                        	vlc_bool_t b_die;
                        
                        
                        	int ch;
                        	int input;
                        
                        	int default_ch;
                        	int default_input;
                        };
                        
                        /* */
                        static int Read( access_t *, uint8_t *, int );
                        static int Control( access_t *, int, va_list );
                        
                        /* */
                        static int Connect( access_t *, int64_t );
                        static void Disconnect( access_t * );
                        
                        /*****************************************************************************
                         * Open:
                         *****************************************************************************/
                        static int Open( vlc_object_t *p_this )
                        {
                            access_t     *p_access = (access_t*)p_this;
                        //	intf_thread_t *p_intf = (intf_thread_t *)p_this;
                            access_sys_t *p_sys;
                            char         *psz, *p;
                        
                        	int i,j;
                        
                        	    //vlc_value_t val;
                        
                            /* Set up p_access */
                            p_access->pf_read = Read;
                            p_access->pf_block = NULL;
                            p_access->pf_control = Control;
                        	p_access->pf_seek = NULL;
                            p_access->info.i_update = 0;
                            p_access->info.i_size = 0;
                            p_access->info.i_pos = 0;
                            p_access->info.b_eof = VLC_FALSE;
                            p_access->info.i_title = 0;
                            p_access->info.i_seekpoint = 0;
                            p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) );
                            memset( p_sys, 0, sizeof( access_sys_t ) );
                            p_sys->fdCommand = -1;
                        	p_sys->fd = -1;
                            p_sys->psz_slingbox = NULL;
                        	p_sys->VideoSupplementChange = VLC_FALSE;
                        	p_sys->b_die = VLC_FALSE;
                        
                        
                        	
                            var_Create( p_access, "slingbox-user", VLC_VAR_STRING |VLC_VAR_DOINHERIT );
                            var_Create( p_access, "slingbox-password", VLC_VAR_STRING |VLC_VAR_DOINHERIT );
                            var_Create( p_access, "slingbox-admin", VLC_VAR_BOOL |VLC_VAR_DOINHERIT );
                        
                        	var_Create( p_access, "slingbox-port", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
                        	var_Create( p_access, "slingbox-adrs", VLC_VAR_STRING |VLC_VAR_DOINHERIT );
                        
                        
                        	var_Create( p_access, "slingbox-caching", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
                        
                        	var_Create( p_access, "slingbox-channel", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
                        	var_Create( p_access, "slingbox-input", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
                        	
                        	
                        	var_Create( p_access,"slingbox-resolution", VLC_VAR_STRING |VLC_VAR_DOINHERIT );
                        	var_Create( p_access,"slingbox-videobitrate", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
                        	var_Create( p_access,"slingbox-framerate", VLC_VAR_STRING |VLC_VAR_DOINHERIT );
                        	var_Create( p_access,"slingbox-videosmoothness", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
                        	var_Create( p_access,"slingbox-audio", VLC_VAR_STRING |VLC_VAR_DOINHERIT );
                        	var_Create( p_access,"slingbox-iframe", VLC_VAR_INTEGER |VLC_VAR_DOINHERIT );
                        
                        	var_Create( p_access, "slingbox-log", VLC_VAR_BOOL |VLC_VAR_DOINHERIT );
                        
                            /* Parse URI - remove spaces */
                            p = psz = strdup( p_access->psz_path );
                            while( (p = strchr( p, ' ' )) != NULL )
                                *p = '+';
                            vlc_UrlParse( &p_sys->url, psz, 0 );
                            free( psz );
                        
                            if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' )
                            {
                                msg_Warn( p_access, "invalid host -> take %s",var_GetString(p_access,"slingbox-adrs") );
                        		p_sys->url.psz_host = var_GetString(p_access,"slingbox-adrs");
                        
                            }
                            if( p_sys->url.psz_host == NULL || *p_sys->url.psz_host == '\0' )
                            {
                                msg_Err( p_access, "invalid host -> take %s",var_GetString(p_access,"slingbox-adrs") );
                        		return VLC_EGENERIC;
                        	}
                            if( p_sys->url.i_port <= 0 )
                              p_sys->url.i_port = var_GetInteger( p_access, "slingbox-port" );
                         
                        	var_AddCallback (p_access->p_vlc, "key-pressed", KeyHandler, p_access);
                        
                        
                        	p_sys->endtime = 0;
                        	p_sys->default_ch = 0;
                        	p_sys->default_input = -1;
                        	
                        	if ( p_sys->url.psz_path ) {
                        
                        		msg_Dbg( p_access ,"Parameter : %s",p_sys->url.psz_path);
                        
                        		p = p_sys->url.psz_path;
                        		while( (p = strchr( p, '/' )) != NULL ) {
                        			p++;
                        			if (*p) {
                        				if (!m_strnicmp(p,"time",4)) {
                        					i = 0;
                        					j = 0;
                        					p+= 4;
                        
                        					while (j < 3 ) { 
                        
                        						i *= 60;
                        						i += atoi(p);
                        						j++;
                        
                        						while ( *p >= '0' && *p <= '9' ) p++;
                        						if ( *p != ':' ) break;
                        						p++;
                        
                        					}
                        
                        					if ( j == 2 ) i *= 60; // No second then it hour:min
                        
                        					p_sys->endtime = time( NULL ) + i;
                        
                        					msg_Info( p_access, "Exit in %d second", i );
                        
                        				}
                        
                        				if (!m_strnicmp(p,"channel",7)) {
                        					p_sys->default_ch = atoi(&p[7]);
                        					msg_Info(p_access, "Def channel %d",p_sys->default_ch);
                        					p++;
                        				}
                        
                        				if (!m_strnicmp(p,"input",5)) {
                        					p_sys->default_input = atoi(&p[5]);
                        					msg_Info(p_access, "Def input %d",p_sys->default_input);
                        					p++;
                        				}
                        			}
                        		}
                        	}
                        
                        
                            msg_Dbg( p_access, "slingbox: server='%s' port=%d file='%s", p_sys->url.psz_host, p_sys->url.i_port, p_sys->url.psz_path );
                        
                            if( Connect( p_access, 0 ) )
                            {
                        		msg_Err( p_access, "slingbox: server='%s' port=%d file='%s", p_sys->url.psz_host, p_sys->url.i_port, p_sys->url.psz_path );
                        		return VLC_EGENERIC;
                            }
                        
                        
                        	msg_Dbg( p_access ,"Start Read Command Thread");
                        	vlc_thread_create( p_access, "Slingbox Command thread", ReadCommand, VLC_THREAD_PRIORITY_LOW, VLC_FALSE );
                        	
                        	return VLC_SUCCESS;
                        
                        }
                        
                        /*****************************************************************************
                         * Close:
                         *****************************************************************************/
                        static void Close( vlc_object_t *p_this )
                        {
                            access_t     *p_access = (access_t*)p_this;
                            access_sys_t *p_sys = p_access->p_sys;
                        
                        	p_sys->b_die = VLC_TRUE;
                        
                        	vlc_UrlClean( &p_sys->url );
                            //if( p_sys->psz_slingbox ) free( p_sys->psz_slingbox );
                        
                        	var_DelCallback (p_access->p_vlc, "key-pressed", KeyHandler, p_access);
                        
                        	Disconnect( p_access );
                           
                        	
                        	free( p_sys );
                        }
                        
                        
                        
                        
                        /*****************************************************************************
                         * Control:
                         *****************************************************************************/
                        static int Control( access_t *p_access, int i_query, va_list args )
                        {
                        
                        //    access_sys_t *p_sys = p_access->p_sys;
                            vlc_bool_t   *pb_bool;
                            int          *pi_int;
                            int64_t      *pi_64;
                          //  vlc_meta_t **pp_meta;
                        
                            switch( i_query )
                            {
                                /* */
                                case ACCESS_CAN_SEEK:
                                    pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
                                    *pb_bool = VLC_FALSE;
                                    break;
                                case ACCESS_CAN_FASTSEEK:
                                    pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
                                    *pb_bool = VLC_FALSE;
                                    break;
                                case ACCESS_CAN_PAUSE:
                                case ACCESS_CAN_CONTROL_PACE:
                                    pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* );
                        
                        #if 0       /* Disable for now until we have a clock synchro algo
                                     * which works with something else than MPEG over UDP */
                                    *pb_bool = p_sys->b_pace_control;
                        #endif
                                    *pb_bool = VLC_TRUE;
                                    break;
                        
                                /* */
                                case ACCESS_GET_MTU:
                                    pi_int = (int*)va_arg( args, int * );
                                    *pi_int = 0;
                                    break;
                        
                                case ACCESS_GET_PTS_DELAY:
                                    pi_64 = (int64_t*)va_arg( args, int64_t * );
                                    *pi_64 = (int64_t)var_GetInteger( p_access, "slingbox-caching" ) * 1000;
                        		    msg_Dbg( p_access, "slingbox-caching %dms",(int)var_GetInteger( p_access, "slingbox-caching" ));
                        
                                    break;
                        
                                /* */
                                case ACCESS_SET_PAUSE_STATE:
                                    break;
                        
                                case ACCESS_GET_META:
                                 /*   pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
                                    *pp_meta = vlc_meta_New();
                        
                                    if( p_sys->psz_icy_name )
                                        vlc_meta_Add( *pp_meta, VLC_META_TITLE,
                                                      p_sys->psz_icy_name );
                                    if( p_sys->psz_icy_genre )
                                        vlc_meta_Add( *pp_meta, VLC_META_GENRE,
                                                      p_sys->psz_icy_genre );
                                    if( p_sys->psz_icy_title )
                                        vlc_meta_Add( *pp_meta, VLC_META_NOW_PLAYING,
                                                      p_sys->psz_icy_title );
                                    break;
                        */
                                case ACCESS_GET_TITLE_INFO:
                                case ACCESS_SET_TITLE:
                                case ACCESS_SET_SEEKPOINT:
                                case ACCESS_SET_PRIVATE_ID_STATE:
                                    return VLC_EGENERIC;
                        
                                default:
                                    msg_Warn( p_access, "unimplemented query in control" );
                                    return VLC_EGENERIC;
                        
                            }
                            return VLC_SUCCESS;
                        }
                        
                        unsigned short SlingBoxMessageCode = 0;
                        unsigned short SlingBoxMessageSeq = 0x6F;
                        struct SlingBoxMessage
                        {
                        	unsigned short Header;		// 0x0101
                        	unsigned short Code;		// This is a number that is grab from the first packet from the slingbox then always kept the same number
                        	unsigned short MessageId;	//  Unique number to identify the message
                        	unsigned short Var4;		// Always 0
                        	unsigned short Sequence;	// Sequencial number (answer will have the same number)
                        	unsigned short Direction;		// 0 from slingbox and 0x8000 from software (maybe direction)
                        	unsigned short Var7;			
                        	unsigned short Var8;		
                        	unsigned short Size;		// Size of the buffer (without header)
                        	unsigned short Encode;		// 2000 -> Encoded buffer
                        	unsigned short Var11;
                        	unsigned short Var12;
                        	unsigned short Var13;
                        	unsigned short Var14;
                        	unsigned short Var15;
                        	unsigned short Var16;
                        };
                        
                        
                        
                        static inline void _crypt(unsigned long*in ,unsigned long*out)
                        {
                        	const unsigned long key[] = {0xBCDEAAAA,0x87FBBBBA,0x7CCCCFFA,0xDDDDAABC};
                        	unsigned long v1 = in[0];
                        	unsigned long v2 = in[1];
                        	unsigned long z = 0;
                        	int i;
                        	for ( i = 0 ; i < 32 ; i ++ ) {
                        		z -= 0x61C88647;
                        		v1 += ((v2 >> 5) + key[1] ) ^ ((v2 << 4) + key[0]) ^ (z+v2); 
                        		v2 += ((v1 >> 5) + key[3] ) ^ ((v1 << 4) + key[2]) ^ (z+v1); 
                        	}
                        	out[0] = v1;
                        	out[1] = v2;
                        }
                        
                        static inline void _uncrypt(unsigned long*in ,unsigned long*out)
                        {
                        	const unsigned long key[] = {0xBCDEAAAA,0x87FBBBBA,0x7CCCCFFA,0xDDDDAABC};
                        	unsigned long v1 = in[0];
                        	unsigned long v2 = in[1];
                        	unsigned long z = 0xc6ef3720;
                        	int i;
                        	for (  i = 0 ; i < 32 ; i ++ ) {
                        		v2 -= ((v1 >> 5) + key[3] ) ^ ((v1 << 4) + key[2] ) ^ (z+v1); 
                        		v1 -= ((v2 >> 5) + key[1] ) ^ ((v2 << 4) + key[0] ) ^ (z+v2); 
                        		z += 0x61C88647;
                        
                        	}
                        	out[0] = v1;
                        	out[1] = v2;
                        }
                        
                        void crypt(void*in ,void*out, int Size)
                        {
                        	int i;
                        	for ( i = 0 ; i < Size ;i += 8 ) 
                        		_crypt((unsigned long*)&((unsigned char*)in)[i],(unsigned long*)&((unsigned char*)out)[i]);
                        }
                        
                        void uncrypt(void *in ,void *out, int Size)
                        {
                        	int i;
                        	for ( i = 0 ; i < Size ;i += 8 ) 
                        		_uncrypt((unsigned long*)&((unsigned char*)in)[i],(unsigned long*)&((unsigned char*)out)[i]);
                        }
                        
                        void CopyStr( short *target , const char *source , int size)
                        {
                        	if ( size > 0 ) memset(target,0,size*2);
                        	while(size && *source) {
                        		*target++ = *source++;
                        		if ( size > 0 ) size--;
                        	}
                        	if ( size < 0 ) *target = 0;
                        }
                        
                        void _DumpHex(access_t *p_access,void *buffer,unsigned long size )
                        {
                        
                        	unsigned long i,j;
                        	char Line[1024];
                        	for (  i = 0 ; i < size ; i += 16 ) {
                        
                        		
                        		Line[0] = 0;
                        		for ( j = i ; j < size && j < i + 16 ; j ++ ) {
                        			sprintf(&Line[strlen(Line)],"%02X%c",((unsigned char*)buffer)[j],j%4 != 3?' ':'-');
                        		}
                        
                        		for ( ; j < i + 16 ; j ++ ) {
                        			strcat(Line,"   ");
                        		}
                        
                        /*
                        		for ( j = i ; j < size && j < i + 16 ; j ++ ) {
                        			char str[2];
                        			str[0] = ((BYTE*)buffer)[j];
                        			if ( !isprint(str[0]) || str[0] == '\n' || str[0] == 'r' ) { 
                        				str[0] = '.';
                        			}
                        			str[1] = (char)NULL;
                        			strcat(Line,str);
                        		}
                        */		
                        		msg_Dbg(p_access,"%04X> %s",(int)i,Line);
                        
                        	}
                        }
                        
                        void ShowInfo(access_t *p_access)
                        {
                            access_sys_t   *p_sys = p_access->p_sys;
                        	vout_OSDMessage( p_access, 0, "Channel %d\nInput %d", p_sys->ch, p_sys->input );
                        }
                        
                        
                        void SendSlingBoxMessage( access_t *p_access, unsigned short MessageId,unsigned short Size, void *Buffer, vlc_bool_t Encode)
                        {
                            access_sys_t   *p_sys = p_access->p_sys;
                        
                        	unsigned short _Encode = Encode?0x2000:0;
                        	unsigned short Seq = SlingBoxMessageCode?SlingBoxMessageSeq:0;
                        	unsigned short dir = SlingBoxMessageCode?0x8000:0;
                        	struct SlingBoxMessage Header = { 0x0101, SlingBoxMessageCode,MessageId,0,Seq,dir,0,0,Size,_Encode,0,0,0,0,0,0 };
                        
                        	if ( var_GetBool( p_access, "slingbox-log" ) ) {
                        		struct SlingBoxMessage *s = &Header;
                        		msg_Dbg(p_access,"Send command");
                        		msg_Dbg(p_access,"Head  %04X Code  %04X MgsId  %04X ????? %04X",s->Header,s->Code,s->MessageId,s->Var4);
                        		msg_Dbg(p_access,"Sequ  %04X dir   %04X ?????  %04X ????? %04X",s->Sequence,s->Direction,s->Var7,s->Var8);
                        		msg_Dbg(p_access,"Size  %04X Enc   %04X ?????  %04X ????? %04X",s->Size,s->Encode,s->Var11,s->Var12);
                        		msg_Dbg(p_access,"????? %04X ????? %04X ?????  %04X ????? %04X",s->Var13,s->Var14,s->Var15,s->Var16);
                        		_DumpHex(p_access,Buffer,Size);
                        	}
                        
                        	if ( Encode ) {
                        		crypt(Buffer,Buffer,Size);
                        	}
                        
                        	net_Write(VLC_OBJECT(p_access), p_sys->fdCommand, p_sys->p_vsCommand ,(void*)&Header ,32);
                        	net_Write(VLC_OBJECT(p_access), p_sys->fdCommand, p_sys->p_vsCommand ,Buffer,Size);
                        }
                        
                        void	ReceiveSlingBoxMessage(access_t *p_access , vlc_bool_t block)
                        {
                            access_sys_t   *p_sys = p_access->p_sys;
                        
                        	uint8_t *buf[1024];
                            int i_read;
                        	if ( block ) {
                        		i_read = net_Read( p_access, p_sys->fdCommand, p_sys->p_vsCommand, (void*)buf, 1024 , VLC_FALSE );
                        	}
                        	else {
                        		i_read = net_ReadNonBlock( p_access, p_sys->fdCommand, p_sys->p_vsCommand, (void*)buf, 1024 , VLC_FALSE );
                        	}
                        
                        	if ( i_read > 0 ) {
                        
                        		if ( i_read >= (int)sizeof(struct SlingBoxMessage) ) {
                        
                        			struct SlingBoxMessage *s = (struct SlingBoxMessage*) buf;
                        
                        			if ( block ) SlingBoxMessageCode = s->Code;
                        
                        			if ( (int)sizeof(struct SlingBoxMessage) + s->Size > i_read ) {
                        				msg_Err(p_access,"Receive short buffer %d (%d,%d)", i_read , (int)sizeof(struct SlingBoxMessage) , s->Size);
                        				msg_Err(p_access,"Head  %04X Code  %04X MgsId  %04X ????? %04X",s->Header,s->Code,s->MessageId,s->Var4);
                        				msg_Err(p_access,"Sequ  %04X dir   %04X ?????  %04X ????? %04X",s->Sequence,s->Direction,s->Var7,s->Var8);
                        				msg_Err(p_access,"Size  %04X Enc   %04X ?????  %04X ????? %04X",s->Size,s->Encode,s->Var11,s->Var12);
                        				msg_Err(p_access,"????? %04X ????? %04X ?????  %04X ????? %04X",s->Var13,s->Var14,s->Var15,s->Var16);
                        			}
                        			else {
                        
                        				if ( s->Encode == 0x2000 ) uncrypt(&s[1],&s[1],s->Size);
                        
                        				if ( s->MessageId == 0x0065 && s->Size == 0x0078 ) {
                        					short *d = (short*)&s[1];
                        					p_sys->ch = d[0];
                        					ShowInfo(p_access);
                        				}
                        				if ( s->MessageId == 0x0065 && s->Size == 0x0008 ) {
                        					short *d = (short*)&s[1];
                        					p_sys->input = d[0];
                        					ShowInfo(p_access);
                        				}
                        
                        				if (var_GetBool( p_access, "slingbox-log" )) {
                        					msg_Dbg(p_access,"Receive command (buf size %d)",i_read);
                        					msg_Dbg(p_access,"Head  %04X Code  %04X MgsId  %04X ????? %04X",s->Header,s->Code,s->MessageId,s->Var4);
                        					msg_Dbg(p_access,"Sequ  %04X dir   %04X ?????  %04X ????? %04X",s->Sequence,s->Direction,s->Var7,s->Var8);
                        					msg_Dbg(p_access,"Size  %04X Enc   %04X ?????  %04X ????? %04X",s->Size,s->Encode,s->Var11,s->Var12);
                        					msg_Dbg(p_access,"????? %04X ????? %04X ?????  %04X ????? %04X",s->Var13,s->Var14,s->Var15,s->Var16);
                        					_DumpHex(p_access,&s[1],s->Size);
                        				}
                        			}
                        		}
                        		else {
                        			msg_Err(p_access, "Receive short buffer %d (%d)", i_read,(int)sizeof(struct SlingBoxMessage)  );
                        			if ( i_read > 0 ) _DumpHex(p_access,buf,i_read);
                        		}
                        	}
                        	else if ( block ) {
                        		msg_Err(p_access, "Receive short buffer %d on block", i_read  );
                        	}
                        }
                        
                        
                        
                        void slingbox_Log(access_t *p_access)
                        {
                            access_sys_t   *p_sys = p_access->p_sys;
                        
                        	msg_Dbg( p_access, "Login" );
                        
                            net_Printf( VLC_OBJECT(p_access), p_sys->fdCommand, p_sys->p_vsCommand ,"GET /stream.asf HTTP/1.1\r\nAccept: */*\r\nPragma: Sling-Connection-Type=Control, Session-Id=0\r\n\r\n");
                        
                        	struct {
                        		unsigned unknow;
                        		short Access[16];
                        		short Password[16];
                        		short Id[66];
                        	} buf;
                        	memset(&buf,0,sizeof(buf));
                        	CopyStr(buf.Access,var_GetBool( p_access, "slingbox-admin" )?"admin":"user",16);
                        	CopyStr(buf.Password,var_GetString( p_access, "slingbox-password" ) ,16);
                        	CopyStr(buf.Id,var_GetString( p_access, "slingbox-user" ),66);
                        	SendSlingBoxMessage(p_access,0x0067,200,&buf,VLC_TRUE);
                        	ReceiveSlingBoxMessage(p_access,VLC_TRUE);
                        
                        }
                        
                        void slingbox_SetStream(access_t *p_access)
                        {
                        	int i;
                        	unsigned Data[24];
                        
                        	unsigned Size = atoi(var_GetString(p_access,"slingbox-resolution"));
                        	unsigned vb = var_GetInteger(p_access,"slingbox-videobitrate");
                        	unsigned fr = atoi(var_GetString(p_access,"slingbox-framerate"));
                        	unsigned vs = var_GetInteger(p_access,"slingbox-videosmoothness");
                        	unsigned ab = atoi(var_GetString(p_access,"slingbox-audio"));
                        	unsigned ifr = var_GetInteger(p_access,"slingbox-iframe");
                        
                        	if ( vb < 50 ) vb = 50;
                        	if (vb > 8000 ) vb = 8000;
                        //	if (Size > 4 ) Size = 4;
                        //	if (Size < 1 ) Size = 1;
                        
                        	if ( fr < 1 ) fr = 1;
                        	else if ( fr < 6 ) fr = 1;
                        	else if ( fr < 10 ) fr = 6;
                        	else if ( fr < 15 ) fr = 10;
                        	else if ( fr < 20 ) fr = 15;
                        	else if ( fr < 30 ) fr = 20;
                        	else fr = 30;
                        
                        	if ( vs > 64 ) vs = 64;
                        
                        	if ( ab < 16 ) ab = 16;
                        	else if ( ab < 20 ) ab = 16;
                        	else if ( ab < 32 ) ab = 20;
                        	else if ( ab < 40 ) ab = 32;
                        	else if ( ab < 48 ) ab = 40;
                        	else if ( ab < 64 ) ab = 48;
                        	else if ( ab < 96 ) ab = 64;
                        	else ab = 96;
                        
                        	if ( ifr > 30 ) ifr = 30;
                        
                        	msg_Dbg( p_access,"Set Video Bitrate %d Frame rate %d I-Frame(sec) %d Video smoothness %d Size %s Audio Bitrate %d",vb,fr,ifr,vs, var_GetString(p_access,"slingbox-resolution"),ab);
                        		
                        	Data[0] = 0x000000FF; Data[1] = 0x000000FF; Data[2] = Size; Data[3] = 1;
                        	Data[4] = vb + (fr << 16) + (ifr << 24); 
                        	Data[5] = 1 + (vs << 8); 
                        	Data[6] = 3; 
                        	Data[7] = 1;
                        	Data[8] = ab; Data[9] = 3; Data[10] = 1; 
                        	Data[11] = 0x46d4f252; Data[12] = 0x4c5d03e4;Data[13] = 0x04ca1f8d; Data[14] = 0xf1090089;
                        	for (  i = 15; i < 24 ; i ++ ) Data[i] = 0;
                        
                        	SendSlingBoxMessage(p_access,0x00b5,24 * sizeof(unsigned),(void*)&Data,VLC_FALSE);
                        	ReceiveSlingBoxMessage(p_access,VLC_TRUE);
                        
                        }
                        
                        void slingbox_input(access_t *p_access , int input )
                        {
                        	unsigned char Data[8];
                        
                        	access_sys_t *p_sys = p_access->p_sys;
                        
                        	if ( input == -1 ) {
                        		input = p_sys->default_input;
                        	}
                        
                        	if ( input == -1 ) {
                        		input = var_GetInteger(p_access,"slingbox-input");
                        	}
                        	if ( input != -1 ) {
                        
                        		msg_Dbg( p_access, "Input %d", input );
                        
                        		memset(Data,0,8);
                        		Data[0]=input;
                        		SendSlingBoxMessage(p_access,0x0085,8,(void*)&Data,VLC_FALSE);
                        	}
                        }
                        
                        
                        
                        void slingbox_channel(access_t *p_access , int _channel  )
                        {
                        	struct {
                        		unsigned long up_down; // 0 == up, 1 = down (channel = 0)
                        		unsigned long channel;
                        		unsigned long unknow2;
                        		unsigned long unknow3;
                        	} Data;
                        
                        	access_sys_t *p_sys = p_access->p_sys;
                        
                        	if ( _channel == 0  ) {
                        		_channel = p_sys->default_ch;
                        	}
                        
                        	if ( _channel == 0 ) {
                        		_channel = var_GetInteger( p_access, "slingbox-channel" );
                        	}
                        
                        	if ( _channel != 0 ) {
                        
                        		msg_Dbg( p_access, "Channel %d", _channel );
                        
                        		Data.channel = _channel;
                        		Data.up_down = 2;
                        		Data.unknow2 = 0xFF000000;
                        		Data.unknow3 = 0;
                        
                        		SendSlingBoxMessage(p_access,0x0089,4 * sizeof(unsigned long),(void*)&Data,VLC_FALSE);
                        	}
                        }
                        
                        void slingbox_channel_up(access_t *p_access   )
                        {
                        	struct {
                        		unsigned long up_down; // 0 == up, 1 = down (channel = 0)
                        		unsigned long channel;
                        		unsigned long unknow2;
                        		unsigned long unknow3;
                        	} Data;
                        
                        
                        	msg_Dbg( p_access, "Channel up" );
                        
                        
                        	Data.channel = 0;
                        	Data.up_down = 0;
                        	Data.unknow2 = 0x000000FF;
                        	Data.unknow3 = 0;
                        
                        	SendSlingBoxMessage(p_access,0x0089,4 * sizeof(unsigned long),(void*)&Data,VLC_FALSE);
                        
                        }
                        
                        void slingbox_channel_down(access_t *p_access   )
                        {
                        	struct {
                        		unsigned long up_down; // 0 == up, 1 = down (channel = 0)
                        		unsigned long channel;
                        		unsigned long unknow2;
                        		unsigned long unknow3;
                        	} Data;
                        
                        
                        	msg_Dbg( p_access, "Channel Down" );
                        
                        
                        	Data.channel = 0;
                        	Data.up_down = 1;
                        	Data.unknow2 = 0x000000FF;
                        	Data.unknow3 = 0;
                        
                        	SendSlingBoxMessage(p_access,0x0089,4 * sizeof(unsigned long),(void*)&Data,VLC_FALSE);
                        
                        }
                        
                        void slingbox_unblock(access_t *p_access)
                        {
                        	/*
                        	> Head  0101 Code  4616 MgsId  00A6 ????? 0000
                        > Sequ  006B dir   8000 ?????  0000 ????? 0000
                        > Size  0060 Enc   2000 ?????  0000 ????? 0000
                        > ????? 0000 ????? 0000 ?????  0000 ????? 0000
                        00 01 00 00-00 00 00 00-00 00 00 00-00 00 00 00-................
                        00 00 1D 00-00 00 00 00-00 00 00 00-00 00 00 00-................
                        00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00-................
                        00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00-................
                        00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00-................
                        00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00-................
                        */
                        	msg_Dbg( p_access, "Unlock" );
                        
                        	unsigned char Data[0x60];
                        	Data[1] = 1;
                        	Data[18] = 0x1D;
                        	SendSlingBoxMessage(p_access,0x00A6,0x60,(void*)&Data,VLC_FALSE);
                        	
                        }
                        
                        void slingbox_startstream( access_t *p_access )
                        {
                        	msg_Dbg( p_access, "Start Stream" );
                        
                        	unsigned char mes[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
                        	SendSlingBoxMessage(p_access,0x007E,8,mes,VLC_TRUE);
                        }
                        
                        /*****************************************************************************
                         * Connect:
                         *****************************************************************************/
                        static int Connect( access_t *p_access, int64_t i_tell )
                        {
                        	
                            access_sys_t   *p_sys = p_access->p_sys;
                        
                            p_access->info.i_size = 0;
                            p_access->info.i_pos  = i_tell;
                            p_access->info.b_eof  = VLC_FALSE;
                        
                            /* Open control connection */
                            p_sys->fdCommand = net_ConnectTCP( p_access, p_sys->url.psz_host, p_sys->url.i_port );
                            if( p_sys->fdCommand < 0 )
                            {
                                msg_Err( p_access, "cannot connect to %s:%d (Command)", p_sys->url.psz_host, p_sys->url.i_port );
                                return VLC_EGENERIC;
                            }
                        	else {
                        		msg_Dbg( p_access, "Connected to %s:%d (Command)", p_sys->url.psz_host, p_sys->url.i_port );
                        	}
                        
                        	slingbox_Log( p_access );
                        	//slingbox_input(p_access,-1);
                        	slingbox_channel(p_access,0);
                        	//slingbox_unblock(p_access);
                        	slingbox_startstream( p_access );
                        	slingbox_SetStream( p_access );
                        	slingbox_input(p_access,-1);
                        
                        	// Open stream connection
                            p_sys->fd = net_ConnectTCP( p_access, p_sys->url.psz_host, p_sys->url.i_port );
                        	if( p_sys->fd < 0 )
                            {
                                msg_Err( p_access, "cannot connect to %s:%d (Stream)", p_sys->url.psz_host, p_sys->url.i_port );
                                return VLC_EGENERIC;
                            }
                        	else {
                                msg_Dbg( p_access, "Connected to %s:%d (Stream)", p_sys->url.psz_host, p_sys->url.i_port );
                        	}
                        
                        	net_Printf( VLC_OBJECT(p_access), p_sys->fd, p_sys->p_vs ,"GET /stream.asf HTTP/1.1\r\nAccept: */*\r\nPragma: Sling-Connection-Type=Stream, Session-Id=%d\r\n\r\n",SlingBoxMessageCode);
                        
                        	return VLC_SUCCESS;
                        }
                        
                        /*****************************************************************************
                         * Read: Read up to i_len bytes from the http connection and place in
                         * p_buffer. Return the actual number of bytes read
                         *****************************************************************************/
                        static int Read( access_t *p_access, uint8_t *p_buffer, int i_len )
                        {
                        	const unsigned long VideoHeader[] = {
                        		0xbc19efc0,
                        		0x11cf5b4d,
                        		0x8000fda8,
                        		0x2b445c5f
                        	};
                        
                        	unsigned i;
                        	uint8_t *h;
                        
                        
                        
                            access_sys_t *p_sys = p_access->p_sys;
                        
                        
                        	if ( p_sys->endtime != 0 && p_sys->endtime < time( NULL ) ) 
                        	{
                        		msg_Dbg( p_access,"Exit VLC");
                                p_access->p_vlc->b_die = VLC_TRUE;
                                //ClearChannels( p_intf, p_vout );
                        	}
                        
                        
                        
                        	int i_read = net_Read( p_access, p_sys->fd, p_sys->p_vs, p_buffer, i_len , VLC_FALSE );
                        	
                        
                        	// Change a little bit the video header because VLC decoder don't like the way slingbox do
                        	if ( p_sys->VideoSupplementChange == VLC_FALSE) {
                        		for (  i = 0 ; i < i_len - 4*sizeof(unsigned) + 1 ; i ++ ) {
                        
                        			// Search for UID of video stream
                        			if ( ((unsigned long*)(&p_buffer[i]))[0] ==  VideoHeader[0] && 
                        				 ((unsigned long*)(&p_buffer[i]))[1] ==  VideoHeader[1] &&
                        				 ((unsigned long*)(&p_buffer[i]))[2] ==  VideoHeader[2] &&
                        				 ((unsigned long*)(&p_buffer[i]))[3] ==  VideoHeader[3] ) {
                        
                        
                        				 // h <- Extra data
                        				if ( i + 105 < i_len - 4*sizeof(unsigned) ) {
                        					h = &p_buffer[i];
                        					h += 105;
                        					 
                        
                        					 msg_Dbg( p_access,"Make correction for WMV3 %02X%02X%02X%02X",
                        						 (int)h[0],
                        						 (int)h[1],
                        						 (int)h[2],
                        						 (int)h[3]
                        					 );
                        
                        					h[3] += 1; // Last bit of the 4th byte must be 1 to kept ffmpeg happy
                        
                        					p_sys->VideoSupplementChange = VLC_TRUE;
                        				}
                        			}
                        		}
                        	}
                        
                        	return i_read;
                        
                        }
                        
                        static int ReadCommand( vlc_object_t *p_this )
                        {
                            access_t     *p_access = (access_t*)p_this;
                            access_sys_t *p_sys = p_access->p_sys;
                        
                         
                            vlc_thread_ready( p_this );
                        
                            while( !p_sys->b_die )
                            {
                        		ReceiveSlingBoxMessage(p_access,VLC_FALSE);
                        		msleep( INPUT_ERROR_SLEEP );
                            }
                        
                            return VLC_SUCCESS;
                        }
                        
                        
                        /*****************************************************************************
                         * Disconnect:
                         *****************************************************************************/
                        static void Disconnect( access_t *p_access )
                        {
                            access_sys_t *p_sys = p_access->p_sys;
                        
                            if( p_sys->fd != -1)
                            {
                                net_Close(p_sys->fd);
                                p_sys->fd = -1;
                            }
                        
                            if( p_sys->fdCommand != -1)
                            {
                                net_Close(p_sys->fdCommand);
                                p_sys->fdCommand = -1;
                            }
                        
                        }
                        
                        
                        static int KeyHandler (vlc_object_t *obj, char const *varname,
                                               vlc_value_t oldval, vlc_value_t newval, void *data)
                        {
                            access_t *p_access = data;
                            struct hotkey *key;
                        
                            (void)oldval;
                            (void)obj;
                        
                        
                            for (key = p_access->p_vlc->p_hotkeys; key->psz_action != NULL; key++)
                            {
                        
                        		if (key->i_key == newval.i_int)
                                {
                        
                        /*
                        			if (key->i_action == ACTIONID_NAV_LEFT)
                        				slingbox_input(p_access,0);
                        			if (key->i_action == ACTIONID_NAV_RIGHT)
                        				slingbox_input(p_access,2);
                        */
                        
                                    if (key->i_action == ACTIONID_NAV_UP)
                                        slingbox_channel_up(p_access);
                                    if (key->i_action == ACTIONID_NAV_DOWN)
                                        slingbox_channel_down(p_access);
                        			if (key->i_action == ACTIONID_NAV_ACTIVATE) {
                        				ShowInfo(p_access);
                        			}
                        
                                    break;
                                }
                            }
                        
                            return VLC_SUCCESS;
                        }
                        Attached Files
                        Nirwana Project, the Android/Win 7 hybrid system!

                        1X Ainol Novo Flame Tab
                        4X MK808b
                        3x Perixx Touchpads
                        3x 7 inch Screens
                        1X 7 inch motorized Screen
                        1x Win 7 PC

                        Comment

                        Working...
                        X