Re: [RFC PATCH 2/2] Initial version of RDS Control utility Signed-off-by: Konke Radlow krad...@cisco.com

2012-07-30 Thread Hans Verkuil
On Sat July 28 2012 13:11:13 Hans de Goede wrote:
 Hi,
 
 Overall this looks good, but some of the code, for example the set/get freq 
 and
 get/set tuner stuff seems to be a 1 on 1 copy of code from v4l2-ctrl, please
 factor this out into a common file which can be shared between both
 utilities (I think Hans V's recent work on splitting v4l2-ctl into multiple
 files comes a long way towards this).

I'm not sure how valuable this is. If we do this, then that means a fair amount
of work in v4l2-ctl (although the split was a major step forward in that 
direction).

There are a bunch of utilities that all share some common code in that respect.
But they are all stand-alone and I would have to think carefully how to organize
the code if you want to make it easy to share code.

Bottom-line: let's keep this as a separate project and not mix it with rds-ctl.

Regards,

Hans

 
 Regards,
 
 Hans
 
 On 07/25/2012 07:44 PM, Konke Radlow wrote:
  ---
Makefile.am   |3 +-
configure.ac  |1 +
utils/rds-ctl/Makefile.am |5 +
utils/rds-ctl/rds-ctl.cpp |  978 
  +
4 files changed, 986 insertions(+), 1 deletion(-)
create mode 100644 utils/rds-ctl/Makefile.am
create mode 100644 utils/rds-ctl/rds-ctl.cpp
 
  diff --git a/Makefile.am b/Makefile.am
  index 6707f5f..47103a1 100644
  --- a/Makefile.am
  +++ b/Makefile.am
  @@ -18,7 +18,8 @@ SUBDIRS += \
  utils/v4l2-compliance \
  utils/v4l2-ctl \
  utils/v4l2-dbg \
  -   utils/v4l2-sysfs-path
  +   utils/v4l2-sysfs-path \
  +   utils/rds-ctl
 
if LINUX_OS
SUBDIRS += \
  diff --git a/configure.ac b/configure.ac
  index 1d7eb29..1ad99e6 100644
  --- a/configure.ac
  +++ b/configure.ac
  @@ -28,6 +28,7 @@ AC_CONFIG_FILES([Makefile
  utils/v4l2-sysfs-path/Makefile
  utils/xc3028-firmware/Makefile
  utils/qv4l2/Makefile
  +   utils/rds-ctl/Makefile
 
  contrib/freebsd/Makefile
  contrib/test/Makefile
  diff --git a/utils/rds-ctl/Makefile.am b/utils/rds-ctl/Makefile.am
  new file mode 100644
  index 000..9a84257
  --- /dev/null
  +++ b/utils/rds-ctl/Makefile.am
  @@ -0,0 +1,5 @@
  +bin_PROGRAMS = rds-ctl
  +
  +rds_ctl_SOURCES = rds-ctl.cpp
  +rds_ctl_LDADD = ../../lib/libv4l2/libv4l2.la 
  ../../lib/libv4l2rds/libv4l2rds.la
  +
  diff --git a/utils/rds-ctl/rds-ctl.cpp b/utils/rds-ctl/rds-ctl.cpp
  new file mode 100644
  index 000..8ddb969
  --- /dev/null
  +++ b/utils/rds-ctl/rds-ctl.cpp
  @@ -0,0 +1,978 @@
  +/*
  + * rds-ctl.cpp is based on v4l2-ctl.cpp
  + *
  + * the following applies for all RDS related parts:
  + * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights 
  reserved.
  + * Author: Konke Radlow korad...@gmail.com
  + *
  + * This program is free software; you can redistribute it and/or modify
  + * it under the terms of the GNU Lesser General Public License as 
  published by
  + * the Free Software Foundation; either version 2.1 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, Suite 500, Boston, MA  02110-1335 
   USA
  + */
  +
  +#include unistd.h
  +#include stdlib.h
  +#include stdio.h
  +#include string.h
  +#include wchar.h
  +#include locale.h
  +#include inttypes.h
  +#include getopt.h
  +#include sys/types.h
  +#include fcntl.h
  +#include errno.h
  +#include sys/ioctl.h
  +#include sys/time.h
  +#include dirent.h
  +#include config.h
  +#include signal.h
  +
  +#ifdef HAVE_SYS_KLOG_H
  +#include sys/klog.h
  +#endif
  +
  +#include linux/videodev2.h
  +#include libv4l2.h
  +#include libv4l2rds.h
  +
  +#include list
  +#include vector
  +#include map
  +#include string
  +#include algorithm
  +
  +#define ARRAY_SIZE(arr) ((int)(sizeof(arr) / sizeof((arr)[0])))
  +
  +typedef std::vectorstd::string dev_vec;
  +typedef std::mapstd::string, std::string dev_map;
  +
  +/* Short option list
  +
  +   Please keep in alphabetical order.
  +   That makes it easier to see which short options are still free.
  +
  +   In general the lower case is used to set something and the upper
  +   case is used to retrieve a setting. */
  +enum Option {
  +   OptSetDevice = 'd',
  +   OptGetDriverInfo = 'D',
  +   OptGetFreq = 'F',
  +   OptSetFreq = 'f',
  +   OptHelp = 'h',
  +   OptReadRds = 'R',
  +   OptGetTuner = 'T',
  +   OptSetTuner = 't',
  +   OptUseWrapper = 'w',
  +   OptAll = 128,
  +   OptFreqSeek,
  +   OptListDevices,
  +   OptOpenFile,
  +   OptPrintBlock,
  +   OptSilent,
  +   OptTunerIndex,
  +   OptVerbose,
  +   

Re: [RFC PATCH 2/2] Initial version of RDS Control utility Signed-off-by: Konke Radlow krad...@cisco.com

2012-07-28 Thread Hans de Goede

Hi,

Overall this looks good, but some of the code, for example the set/get freq and
get/set tuner stuff seems to be a 1 on 1 copy of code from v4l2-ctrl, please
factor this out into a common file which can be shared between both
utilities (I think Hans V's recent work on splitting v4l2-ctl into multiple
files comes a long way towards this).

Regards,

Hans

On 07/25/2012 07:44 PM, Konke Radlow wrote:

---
  Makefile.am   |3 +-
  configure.ac  |1 +
  utils/rds-ctl/Makefile.am |5 +
  utils/rds-ctl/rds-ctl.cpp |  978 +
  4 files changed, 986 insertions(+), 1 deletion(-)
  create mode 100644 utils/rds-ctl/Makefile.am
  create mode 100644 utils/rds-ctl/rds-ctl.cpp

diff --git a/Makefile.am b/Makefile.am
index 6707f5f..47103a1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -18,7 +18,8 @@ SUBDIRS += \
utils/v4l2-compliance \
utils/v4l2-ctl \
utils/v4l2-dbg \
-   utils/v4l2-sysfs-path
+   utils/v4l2-sysfs-path \
+   utils/rds-ctl

  if LINUX_OS
  SUBDIRS += \
diff --git a/configure.ac b/configure.ac
index 1d7eb29..1ad99e6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,6 +28,7 @@ AC_CONFIG_FILES([Makefile
utils/v4l2-sysfs-path/Makefile
utils/xc3028-firmware/Makefile
utils/qv4l2/Makefile
+   utils/rds-ctl/Makefile

contrib/freebsd/Makefile
contrib/test/Makefile
diff --git a/utils/rds-ctl/Makefile.am b/utils/rds-ctl/Makefile.am
new file mode 100644
index 000..9a84257
--- /dev/null
+++ b/utils/rds-ctl/Makefile.am
@@ -0,0 +1,5 @@
+bin_PROGRAMS = rds-ctl
+
+rds_ctl_SOURCES = rds-ctl.cpp
+rds_ctl_LDADD = ../../lib/libv4l2/libv4l2.la ../../lib/libv4l2rds/libv4l2rds.la
+
diff --git a/utils/rds-ctl/rds-ctl.cpp b/utils/rds-ctl/rds-ctl.cpp
new file mode 100644
index 000..8ddb969
--- /dev/null
+++ b/utils/rds-ctl/rds-ctl.cpp
@@ -0,0 +1,978 @@
+/*
+ * rds-ctl.cpp is based on v4l2-ctl.cpp
+ *
+ * the following applies for all RDS related parts:
+ * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights 
reserved.
+ * Author: Konke Radlow korad...@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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, Suite 500, Boston, MA  02110-1335  USA
+ */
+
+#include unistd.h
+#include stdlib.h
+#include stdio.h
+#include string.h
+#include wchar.h
+#include locale.h
+#include inttypes.h
+#include getopt.h
+#include sys/types.h
+#include fcntl.h
+#include errno.h
+#include sys/ioctl.h
+#include sys/time.h
+#include dirent.h
+#include config.h
+#include signal.h
+
+#ifdef HAVE_SYS_KLOG_H
+#include sys/klog.h
+#endif
+
+#include linux/videodev2.h
+#include libv4l2.h
+#include libv4l2rds.h
+
+#include list
+#include vector
+#include map
+#include string
+#include algorithm
+
+#define ARRAY_SIZE(arr) ((int)(sizeof(arr) / sizeof((arr)[0])))
+
+typedef std::vectorstd::string dev_vec;
+typedef std::mapstd::string, std::string dev_map;
+
+/* Short option list
+
+   Please keep in alphabetical order.
+   That makes it easier to see which short options are still free.
+
+   In general the lower case is used to set something and the upper
+   case is used to retrieve a setting. */
+enum Option {
+   OptSetDevice = 'd',
+   OptGetDriverInfo = 'D',
+   OptGetFreq = 'F',
+   OptSetFreq = 'f',
+   OptHelp = 'h',
+   OptReadRds = 'R',
+   OptGetTuner = 'T',
+   OptSetTuner = 't',
+   OptUseWrapper = 'w',
+   OptAll = 128,
+   OptFreqSeek,
+   OptListDevices,
+   OptOpenFile,
+   OptPrintBlock,
+   OptSilent,
+   OptTunerIndex,
+   OptVerbose,
+   OptWaitLimit,
+   OptLast = 256
+};
+
+struct ctl_parameters {
+   bool terminate_decoding;
+   char options[OptLast];
+   char fd_name[80];
+   bool filemode_active;
+   double freq;
+   uint32_t wait_limit;
+   uint8_t tuner_index;
+   struct v4l2_hw_freq_seek freq_seek;
+};
+
+static struct ctl_parameters params;
+static int app_result;
+
+static struct option long_options[] = {
+   {all, no_argument, 0, OptAll},
+   {device, required_argument, 0, OptSetDevice},
+   {file, required_argument, 0, OptOpenFile},
+   {freq-seek, required_argument, 0, OptFreqSeek},
+   {get-freq, no_argument, 0, OptGetFreq},
+   {get-tuner, no_argument, 0, OptGetTuner},
+   

Re: [RFC PATCH 2/2] Initial version of RDS Control utility Signed-off-by: Konke Radlow krad...@cisco.com

2012-07-27 Thread Hans Verkuil
On Thu July 26 2012 21:13:08 Gregor Jasny wrote:
 On 7/25/12 7:44 PM, Konke Radlow wrote:
 
  +static void print_rds_af(struct v4l2_rds_af_set *af_set)
  +{
  +   int counter = 0;
  +
  +   printf(\nAnnounced AFs: %u, af_set-announced_af);
  +   for (int i = 0; i  af_set-size  i  af_set-announced_af; i++, 
  counter++) {
  +   if (af_set-af[i] = 8750 ) {
  +   printf(\nAF%02d: %.1fMHz, counter, af_set-af[i] / 
  100.0);
  +   continue;
  +   }
  +   printf(\nAF%02d: %.1fkHz, counter, af_set-af[i] / 1000.0);
  +   }
  +}
  +
  +static void print_rds_pi(const struct v4l2_rds *handle)
  +{
  +   printf(\nArea Coverage: %s, v4l2_rds_get_coverage_str(handle));
  +}
  +
  +static void print_rds_data(struct v4l2_rds *handle, uint32_t 
  updated_fields)
  +{
  +   if (params.options[OptPrintBlock])
  +   updated_fields = 0x;
 
 You could use UINT32_MAX here

I wouldn't. It's a bitmask, not a 'normal' integer and with UINT32_MAX you
lose that connection. The only change I'd make here is to use lower-case for the
hex characters instead of upper case, or perhaps changing it to ~0.

 
  +
  +   if (updated_fields  V4L2_RDS_PI  
  +   handle-valid_fields  V4L2_RDS_PI) {
  +   printf(\nPI: %04x, handle-pi);
  +   print_rds_pi(handle);
  +   }
 
  +static int parse_cl(int argc, char **argv)
  +{
  +   int i = 0;
  +   int idx = 0;
  +   int opt = 0;
  +   char short_options[26 * 2 * 2 + 1];
 
 Where comes the 26 and 2 from?

Really? Short options are a-z and A-Z. 26? Alphabet? For each option you need
at most two chars (option + an optional argument specifier).

Anyway, I guess a short comment wouldn't hurt.

Note that the option parsing code is all copied from v4l2-ctl and it's used in
a whole bunch of utilities in v4l-utils.

Regards,

Hans

 Could this be (ARRAY_SIZE(long_options) + 1 ) * 2?
 
 --
 To unsubscribe from this list: send the line unsubscribe linux-media in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 2/2] Initial version of RDS Control utility Signed-off-by: Konke Radlow krad...@cisco.com

2012-07-26 Thread Gregor Jasny
On 7/25/12 7:44 PM, Konke Radlow wrote:
 --- /dev/null
 +++ b/utils/rds-ctl/rds-ctl.cpp
 @@ -0,0 +1,978 @@
 +/*
 + * rds-ctl.cpp is based on v4l2-ctl.cpp
 + * 
 + * the following applies for all RDS related parts:
 + * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights 
 reserved.
 + * Author: Konke Radlow korad...@gmail.com
 + * 
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU Lesser General Public License as published 
 by
 + * the Free Software Foundation; either version 2.1 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, Suite 500, Boston, MA  02110-1335  
 USA
 + */
 +
 +#include unistd.h
 +#include stdlib.h
 +#include stdio.h
 +#include string.h
 +#include wchar.h
 +#include locale.h
 +#include inttypes.h
 +#include getopt.h
 +#include sys/types.h
 +#include fcntl.h
 +#include errno.h
 +#include sys/ioctl.h
 +#include sys/time.h
 +#include dirent.h
 +#include config.h
 +#include signal.h
 +
 +#ifdef HAVE_SYS_KLOG_H
 +#include sys/klog.h
 +#endif

You don't call klog, so you can drop these three lines

 +static int parse_cl(int argc, char **argv)
 +{
 + int i = 0;
 + int idx = 0;
 + int opt = 0;
 + char short_options[26 * 2 * 2 + 1];
 +
 + if (argc == 1) {
 + usage_hint();
 + exit(1);
 + }
 + for (i = 0; long_options[i].name; i++) {
 + if (!isalpha(long_options[i].val))
 + continue;
 + short_options[idx++] = long_options[i].val;
 + if (long_options[i].has_arg == required_argument)
 + short_options[idx++] = ':';
 + }
 + while (1) {
 + // TODO: remove option_index ?
 + int option_index = 0;
 +
 + short_options[idx] = 0;
 + opt = getopt_long(argc, argv, short_options,
 +  long_options, option_index);
 + if (opt == -1)
 + break;
 +
 + params.options[(int)opt] = 1;
 + switch (opt) {
 + case OptSetDevice:
 + strncpy(params.fd_name, optarg, 80);
 + if (optarg[0] = '0'  optarg[0] = '9'  optarg[1] 
 == 0) {

see isdigit from types.h (or std::isdigit from ctypes)


Thanks,
Gregor
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 2/2] Initial version of RDS Control utility Signed-off-by: Konke Radlow krad...@cisco.com

2012-07-26 Thread Gregor Jasny
On 7/25/12 7:44 PM, Konke Radlow wrote:

 +static void print_rds_af(struct v4l2_rds_af_set *af_set)
 +{
 + int counter = 0;
 +
 + printf(\nAnnounced AFs: %u, af_set-announced_af);
 + for (int i = 0; i  af_set-size  i  af_set-announced_af; i++, 
 counter++) {
 + if (af_set-af[i] = 8750 ) {
 + printf(\nAF%02d: %.1fMHz, counter, af_set-af[i] / 
 100.0);
 + continue;
 + }
 + printf(\nAF%02d: %.1fkHz, counter, af_set-af[i] / 1000.0);
 + }
 +}
 +
 +static void print_rds_pi(const struct v4l2_rds *handle)
 +{
 + printf(\nArea Coverage: %s, v4l2_rds_get_coverage_str(handle));
 +}
 +
 +static void print_rds_data(struct v4l2_rds *handle, uint32_t updated_fields)
 +{
 + if (params.options[OptPrintBlock])
 + updated_fields = 0x;

You could use UINT32_MAX here

 +
 + if (updated_fields  V4L2_RDS_PI  
 + handle-valid_fields  V4L2_RDS_PI) {
 + printf(\nPI: %04x, handle-pi);
 + print_rds_pi(handle);
 + }

 +static int parse_cl(int argc, char **argv)
 +{
 + int i = 0;
 + int idx = 0;
 + int opt = 0;
 + char short_options[26 * 2 * 2 + 1];

Where comes the 26 and 2 from?
Could this be (ARRAY_SIZE(long_options) + 1 ) * 2?

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 2/2] Initial version of RDS Control utility Signed-off-by: Konke Radlow krad...@cisco.com

2012-07-26 Thread Konke Radlow
1.
 +#ifdef HAVE_SYS_KLOG_H
 +#include sys/klog.h
 +#endif

I'll drop those lines

2.
 + case OptSetDevice:
 + strncpy(params.fd_name, optarg, 80);
 + if (optarg[0] = '0'  optarg[0] = '9'  optarg[1] 
 == 0) {

I didn't know about the isalpha function, thanks for the hint

3.
 + if (params.options[OptPrintBlock])
 + updated_fields = 0x;

will use that handy definition (UINT32_MAX )

4.
 + int opt = 0;
 + char short_options[26 * 2 * 2 + 1];

the number 26 was taken over from the code of the v4l2-ctl tool. I don't know
where that magic number is coming from. I just checked the v4l2-ctl code again
and there seem to be 26 short options defined in the enum Option type.


Thank you for your comments so far. I'll incorporate them tomorrow
morning when I'm
back on my working machine,

regards,
Konke



On Thu, Jul 26, 2012 at 9:13 PM, Gregor Jasny gja...@googlemail.com wrote:

 On 7/25/12 7:44 PM, Konke Radlow wrote:

  +static void print_rds_af(struct v4l2_rds_af_set *af_set)
  +{
  + int counter = 0;
  +
  + printf(\nAnnounced AFs: %u, af_set-announced_af);
  + for (int i = 0; i  af_set-size  i  af_set-announced_af; i++, 
  counter++) {
  + if (af_set-af[i] = 8750 ) {
  + printf(\nAF%02d: %.1fMHz, counter, af_set-af[i] / 
  100.0);
  + continue;
  + }
  + printf(\nAF%02d: %.1fkHz, counter, af_set-af[i] / 1000.0);
  + }
  +}
  +
  +static void print_rds_pi(const struct v4l2_rds *handle)
  +{
  + printf(\nArea Coverage: %s, v4l2_rds_get_coverage_str(handle));
  +}
  +
  +static void print_rds_data(struct v4l2_rds *handle, uint32_t 
  updated_fields)
  +{
  + if (params.options[OptPrintBlock])
  + updated_fields = 0x;

 You could use UINT32_MAX here

  +
  + if (updated_fields  V4L2_RDS_PI 
  + handle-valid_fields  V4L2_RDS_PI) {
  + printf(\nPI: %04x, handle-pi);
  + print_rds_pi(handle);
  + }

  +static int parse_cl(int argc, char **argv)
  +{
  + int i = 0;
  + int idx = 0;
  + int opt = 0;
  + char short_options[26 * 2 * 2 + 1];

 Where comes the 26 and 2 from?
 Could this be (ARRAY_SIZE(long_options) + 1 ) * 2?

 --
 To unsubscribe from this list: send the line unsubscribe linux-media in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 2/2] Initial version of RDS Control utility Signed-off-by: Konke Radlow krad...@cisco.com

2012-07-25 Thread Konke Radlow
---
 Makefile.am   |3 +-
 configure.ac  |1 +
 utils/rds-ctl/Makefile.am |5 +
 utils/rds-ctl/rds-ctl.cpp |  978 +
 4 files changed, 986 insertions(+), 1 deletion(-)
 create mode 100644 utils/rds-ctl/Makefile.am
 create mode 100644 utils/rds-ctl/rds-ctl.cpp

diff --git a/Makefile.am b/Makefile.am
index 6707f5f..47103a1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -18,7 +18,8 @@ SUBDIRS += \
utils/v4l2-compliance \
utils/v4l2-ctl \
utils/v4l2-dbg \
-   utils/v4l2-sysfs-path
+   utils/v4l2-sysfs-path \
+   utils/rds-ctl
 
 if LINUX_OS
 SUBDIRS += \
diff --git a/configure.ac b/configure.ac
index 1d7eb29..1ad99e6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,6 +28,7 @@ AC_CONFIG_FILES([Makefile
utils/v4l2-sysfs-path/Makefile
utils/xc3028-firmware/Makefile
utils/qv4l2/Makefile
+   utils/rds-ctl/Makefile
 
contrib/freebsd/Makefile
contrib/test/Makefile
diff --git a/utils/rds-ctl/Makefile.am b/utils/rds-ctl/Makefile.am
new file mode 100644
index 000..9a84257
--- /dev/null
+++ b/utils/rds-ctl/Makefile.am
@@ -0,0 +1,5 @@
+bin_PROGRAMS = rds-ctl
+
+rds_ctl_SOURCES = rds-ctl.cpp
+rds_ctl_LDADD = ../../lib/libv4l2/libv4l2.la ../../lib/libv4l2rds/libv4l2rds.la
+
diff --git a/utils/rds-ctl/rds-ctl.cpp b/utils/rds-ctl/rds-ctl.cpp
new file mode 100644
index 000..8ddb969
--- /dev/null
+++ b/utils/rds-ctl/rds-ctl.cpp
@@ -0,0 +1,978 @@
+/*
+ * rds-ctl.cpp is based on v4l2-ctl.cpp
+ * 
+ * the following applies for all RDS related parts:
+ * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights 
reserved.
+ * Author: Konke Radlow korad...@gmail.com
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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, Suite 500, Boston, MA  02110-1335  USA
+ */
+
+#include unistd.h
+#include stdlib.h
+#include stdio.h
+#include string.h
+#include wchar.h
+#include locale.h
+#include inttypes.h
+#include getopt.h
+#include sys/types.h
+#include fcntl.h
+#include errno.h
+#include sys/ioctl.h
+#include sys/time.h
+#include dirent.h
+#include config.h
+#include signal.h
+
+#ifdef HAVE_SYS_KLOG_H
+#include sys/klog.h
+#endif
+
+#include linux/videodev2.h
+#include libv4l2.h
+#include libv4l2rds.h
+
+#include list
+#include vector
+#include map
+#include string
+#include algorithm
+
+#define ARRAY_SIZE(arr) ((int)(sizeof(arr) / sizeof((arr)[0])))
+
+typedef std::vectorstd::string dev_vec;
+typedef std::mapstd::string, std::string dev_map;
+
+/* Short option list
+
+   Please keep in alphabetical order.
+   That makes it easier to see which short options are still free.
+
+   In general the lower case is used to set something and the upper
+   case is used to retrieve a setting. */
+enum Option {
+   OptSetDevice = 'd',
+   OptGetDriverInfo = 'D',
+   OptGetFreq = 'F',
+   OptSetFreq = 'f',
+   OptHelp = 'h',
+   OptReadRds = 'R',
+   OptGetTuner = 'T',
+   OptSetTuner = 't',
+   OptUseWrapper = 'w',
+   OptAll = 128,
+   OptFreqSeek,
+   OptListDevices,
+   OptOpenFile,
+   OptPrintBlock,
+   OptSilent,
+   OptTunerIndex,
+   OptVerbose,
+   OptWaitLimit,
+   OptLast = 256
+};
+
+struct ctl_parameters {
+   bool terminate_decoding;
+   char options[OptLast];
+   char fd_name[80];
+   bool filemode_active;
+   double freq;
+   uint32_t wait_limit;
+   uint8_t tuner_index;
+   struct v4l2_hw_freq_seek freq_seek;
+};
+
+static struct ctl_parameters params;
+static int app_result;
+
+static struct option long_options[] = {
+   {all, no_argument, 0, OptAll},
+   {device, required_argument, 0, OptSetDevice},
+   {file, required_argument, 0, OptOpenFile},
+   {freq-seek, required_argument, 0, OptFreqSeek},
+   {get-freq, no_argument, 0, OptGetFreq},
+   {get-tuner, no_argument, 0, OptGetTuner},
+   {help, no_argument, 0, OptHelp},
+   {info, no_argument, 0, OptGetDriverInfo},
+   {list-devices, no_argument, 0, OptListDevices},
+   {print-block, no_argument, 0, OptPrintBlock},
+   {read-rds, no_argument, 0, OptReadRds},
+   {set-freq, required_argument, 0, OptSetFreq},
+   {tuner-index, required_argument, 0, OptTunerIndex},
+   {verbose, no_argument, 0, OptVerbose},
+