Ticket #285: sa3250ch.patch

File sa3250ch.patch, 5.5 KB (added by mporter@…, 20 years ago)

Adds app and readme

  • contrib/README.sa3250ch

     
     1sa3250ch is a small program that changes channels on a Scientific Atlanta
     2SA3250HD cable box via a 1394 (aka. Firewire) connection. It is based off
     3of 6200ch by Stacey Son (mythdev@son.org).
     4
     5To use this with mythtv do the following:
     6
     7(1) Make sure you have 1394/Firewire drivers installed in your kernel.
     8
     9(2) Install libraw1394, librom1394 and libavc1394.
     10
     11(3) Compile and install "sa3250ch":
     12
     13      # cc -o sa3250ch sa3250ch.c -lrom1394 -lavc1394 -lraw1394
     14      # cp sa3250ch /usr/local/bin
     15
     16(4) Connect a 1394/Firewire cable from your computer to your SA3250HD and test:
     17
     18      # sa3250ch <your_favorite_channel_number>
     19
     20(5) Configure Mythtv to use the channel changer by running the "setup" program and adding to "/usr/local/bin/sa3250ch" to the "External channel change command" field under "Connect source to Input".
     21
     22I'm curious if this works for anybody on other SciAtl boxes when the proper
     23model IDs are added.
     24
     25Matt Porter <mporter@kernel.crashing.org>
  • contrib/sa3250ch.c

     
     1/*
     2 * sa3250ch - an external channel changer for SA3250HD Tuner
     3 * Based off 6200ch.c by Stacey D. Son
     4 *
     5 * Copyright 2004,2005 by Stacey D. Son <mythdev@son.org>
     6 * Copyright 2005 Matt Porter <mporter@kernel.crashing.org>
     7 *
     8 * This program is free software; you can redistribute it and/or modify
     9 * it under the terms of the GNU General Public License as published by
     10 * the Free Software Foundation; either version 2 of the License, or
     11 * (at your option) any later version.
     12 *
     13 * This program is distributed in the hope that it will be useful,
     14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 * GNU General Public License for more details.
     17 *
     18 * You should have received a copy of the GNU General Public License
     19 * along with this program; if not, write to the Free Software Foundation,
     20 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     21 */
     22
     23#include <libavc1394/rom1394.h>
     24#include <libavc1394/avc1394.h>
     25#include <libraw1394/raw1394.h>
     26#include <sys/types.h>
     27#include <stdio.h>
     28#include <errno.h>
     29#include <stdlib.h>
     30
     31/* SA3250HD IDs */
     32#define SA3250HD_VENDOR_ID      0x000011e6
     33#define SA3250HD_MODEL_ID       0x00000be0
     34
     35#define AVC1394_SA3250_COMMAND_CHANNEL 0x000007c00   /* subunit command */
     36#define AVC1394_SA3250_OPERAND_KEY_PRESS 0xe7
     37#define AVC1394_SA3250_OPERAND_KEY_RELEASE 0x67
     38
     39#define CTL_CMD0 AVC1394_CTYPE_CONTROL | AVC1394_SUBUNIT_TYPE_PANEL | \
     40        AVC1394_SUBUNIT_ID_0 | AVC1394_SA3250_COMMAND_CHANNEL
     41#define CTL_CMD1 (0x04 << 24)
     42#define CTL_CMD2 0xff000000
     43
     44#define STARTING_NODE 0
     45
     46void usage()
     47{
     48   fprintf(stderr, "Usage: sa3250ch [-v] <channel_num>\n");
     49   exit(1);
     50}
     51
     52int main (int argc, char *argv[])
     53{
     54   rom1394_directory dir;
     55   int device = -1;
     56   int i;
     57   int verbose = 0;
     58   quadlet_t cmd[3];
     59   int dig[3];
     60   int chn = 708;
     61
     62   if (argc < 2)
     63      usage();
     64
     65   if (argc == 3 && argv[1][0] == '-' && argv[1][1] == 'v') {
     66      verbose = 1;
     67      chn = atoi(argv[2]);
     68   } else {
     69      chn = atoi(argv[1]);
     70   }
     71
     72#ifdef RAW1394_V_0_8
     73   raw1394handle_t handle = raw1394_get_handle();
     74#else
     75   raw1394handle_t handle = raw1394_new_handle();
     76#endif
     77
     78   if (!handle) {
     79      if (!errno) {
     80         fprintf(stderr, "Not Compatible!\n");
     81      } else {
     82         perror("Couldn't get 1394 handle");
     83         fprintf(stderr, "Is ieee1394, driver, and raw1394 loaded?\n");
     84      }
     85      exit(1);
     86   }
     87
     88   if (raw1394_set_port(handle, 0) < 0) {
     89      perror("couldn't set port");
     90      raw1394_destroy_handle(handle);
     91      exit(1);
     92   }
     93
     94   int nc = raw1394_get_nodecount(handle);
     95   for (i=STARTING_NODE; i < nc; ++i) {
     96      if (rom1394_get_directory(handle, i, &dir) < 0) {
     97         fprintf(stderr,"error reading config rom directory for node %d\n", i);
     98         raw1394_destroy_handle(handle);
     99         exit(1);
     100      }
     101
     102      if (verbose)
     103         printf("node %d: vendor_id = 0x%08x model_id = 0x%08x\n",
     104                 i, dir.vendor_id, dir.model_id);
     105               
     106      if ((dir.vendor_id == SA3250HD_VENDOR_ID)  &&
     107          (dir.model_id == SA3250HD_MODEL_ID)) {
     108            device = i;
     109            break;
     110      }
     111   }
     112   
     113   if (device == -1) {
     114        fprintf(stderr, "Could not find SA3250HD on the 1394 bus.\n");
     115        raw1394_destroy_handle(handle);
     116        exit(1);
     117   }
     118
     119   dig[2] = 0x30 | (chn % 10);
     120   dig[1] = 0x30 | ((chn % 100)  / 10);
     121   dig[0] = 0x30 | ((chn % 1000) / 100);
     122
     123   cmd[0] = CTL_CMD0 | AVC1394_SA3250_OPERAND_KEY_PRESS;
     124   cmd[1] = CTL_CMD1 | (dig[0] << 16) | (dig[1] << 8) | dig[2];
     125   cmd[2] = CTL_CMD2;
     126
     127   if (verbose)
     128      printf("AV/C Command: %d%d%d = cmd0=0x%08x cmd2=0x%08x cmd3=0x%08x\n",
     129            dig[0] & 0xf, dig[1] & 0xf, dig[2] & 0xf, cmd[0], cmd[1], cmd[2]);
     130
     131   avc1394_transaction_block(handle, 0, cmd, 3, 1);
     132   cmd[0] = CTL_CMD0 | AVC1394_SA3250_OPERAND_KEY_RELEASE;
     133
     134   if (verbose)
     135      printf("AV/C Command: %d%d%d = cmd0=0x%08x cmd2=0x%08x cmd3=0x%08x\n",
     136            dig[0] & 0xf, dig[1] & 0xf, dig[2] & 0xf, cmd[0], cmd[1], cmd[2]);
     137
     138   avc1394_transaction_block(handle, 0, cmd, 3, 1);
     139
     140   raw1394_destroy_handle(handle);
     141
     142   exit(0);
     143}