Index: ChangeLog
===================================================================
--- ChangeLog	(revision 5975)
+++ ChangeLog	(revision 5977)
@@ -1,5 +1,5 @@
 v. 1.0beta12 - ?
 	* Added user defined RoarDMX events.
-	* Added support for rangeset to libroarlight.
+	* Added support for rangeset to libroarlight, roard and roarlight.
 
 v. 1.0beta11 - Tue Jan 21 2014 21:04 CET
Index: libroarlight/roardmx.c
===================================================================
--- libroarlight/roardmx.c	(revision 5975)
+++ libroarlight/roardmx.c	(revision 5977)
@@ -433,5 +433,5 @@
   return -1;
 
- mes->type = ROAR_ROARDMX_TYPE_SSET;
+ mes->type = ROAR_ROARDMX_TYPE_RANGESET;
 
  return 0;
@@ -487,5 +487,6 @@
  }
 
- if ( (((size_t)index + 1) * 5) > (mes->length - 3) ) {
+ if ( (((size_t)index + 1) * 5) > mes->length ) {
+  ROAR_DBG("roar_roardmx_message_get_rangeval(mes=%p{.length=%i, ...}, start=%p, end=%p, val=%p, index=%i) = ?", mes, (int)mes->length, start, end, val, index);
   roar_err_set(ROAR_ERROR_NOENT);
   return -1;
Index: roarclients/roarlight.c
===================================================================
--- roarclients/roarlight.c	(revision 5961)
+++ roarclients/roarlight.c	(revision 5977)
@@ -95,4 +95,53 @@
 }
 
+static int cmd_rangeset (char * arg) {
+ char * next = arg;
+ char * k, * v;
+ int32_t start, end, val;
+ struct roar_roardmx_message mes;
+
+ roar_roardmx_message_new_rangeset(&mes);
+
+ while (next != NULL) {
+  arg  = next;
+  next = strstr(next, ",");
+  if ( next != NULL ) {
+   *next = 0;
+    next++;
+  }
+
+  k = arg;
+  v = strstr(arg, "=");
+  if ( v == NULL )
+   return -1;
+
+  *v = 0;
+   v++;
+
+  val  = atoi(v);
+
+  v = strstr(arg, "-");
+  if ( v == NULL ) {
+   start = end = atoi(k);
+  } else {
+  *v = 0;
+   v++;
+   start = atoi(k);
+   end = atoi(v);
+  }
+
+//  printf("k='%s'(%i), v='%s'(%i)\n", k, chan, v, val);
+  if ( roar_roardmx_message_add_rangeval(&mes, start, end, val) == -1 ) {
+   return -1;
+  }
+ }
+
+ if ( roar_roardmx_message_send(&mes, g_stream) == -1 ) {
+  return -1;
+ }
+
+ return 0;
+}
+
 static int cmd_event (char * arg) {
  struct roar_roardmx_message mes;
@@ -146,4 +195,12 @@
    i++;
    if ( cmd_sset(argv[i]) == -1 ) {
+    fprintf(stderr, "Error: can not set channels\n");
+   } else {
+    printf("channels changed\n");
+   }
+  } else if ( !strcmp(k, "rangeset") ) {
+   ROAR_CKHAVEARGS(1);
+   i++;
+   if ( cmd_rangeset(argv[i]) == -1 ) {
     fprintf(stderr, "Error: can not set channels\n");
    } else {
Index: roard/codecfilter_roardmx.c
===================================================================
--- roard/codecfilter_roardmx.c	(revision 5961)
+++ roard/codecfilter_roardmx.c	(revision 5977)
@@ -53,4 +53,43 @@
 }
 
+static inline int __read_rangeset(int id, struct roar_stream_server * ss, struct roar_roardmx_message * mes) {
+ uint16_t start, end;
+ uint8_t value;
+ size_t p;
+ int i, c;
+
+ // we ignore errors here at the moment as 0 not < -1
+ c = roar_roardmx_message_numchannels(mes);
+ ROAR_DBG("__read_rangeset(id=%i, ...): Number of subframes: %u", id, c);
+
+ for (i = 0; i < c; i++) {
+  ROAR_DBG("__read_rangeset(id=%i, ...): i=%i", id, i);
+
+  if ( roar_roardmx_message_get_rangeval(mes, &start, &end, &value, i) == -1 ) {
+   ROAR_WARN("__read_rangeset(id=%i, ...): Can not read subframe: %i: %s", id, i, roar_errorstring);
+   return -1;
+  }
+
+  ROAR_DBG("__read_rangeset(id=%i, ...): i=%i, start=%u, end=%u, value=%u", id, i, start, end, value);
+
+  if ( start > end ) {
+   ROAR_WARN("__read_rangeset(id=%i, ...): Bad RoarDMX Rangeset frame: start > end.", id);
+   continue;
+  }
+
+  if ( g_light_state.channels < end ) {
+   ROAR_WARN("__read_rangeset(id=%i, ...): Range out of DMX universe: %u-%u", id, start, end);
+   continue;
+  }
+
+  for (p = start; p <= end; p++) {
+   g_light_state.state[p]   = value;
+   g_light_state.changes[p] = 0xFF; // the channel changed 
+  }
+ }
+
+ return 0;
+}
+
 static inline int __read_events(int id, struct roar_stream_server * ss, struct roar_roardmx_message * mes) {
  const uint8_t * events;
@@ -77,4 +116,5 @@
  switch (type) {
   case ROAR_ROARDMX_TYPE_SSET: return __read_sset(id, ss, &mes); break;
+  case ROAR_ROARDMX_TYPE_RANGESET: return __read_rangeset(id, ss, &mes); break;
   case ROAR_ROARDMX_TYPE_EVENT: return __read_events(id, ss, &mes); break;
  }
