Here you have the methods you mentioned:

BatteryDriver::BatteryDriver(ConfigFile* cf, int section)
    : Driver(cf, section, false, PLAYER_MSGQUEUE_DEFAULT_MAXLEN,
             PLAYER_POWER_CODE)
{

  if(cf->ReadDeviceAddr(&this->can_addr, section, "requires",
                        PLAYER_OPAQUE_CODE, -1, NULL) != 0)
  {
    this->SetError(-1);
    return;
  }
  printf("Will subscribe to opaque:%d\n", this->can_addr.index);

  // Read the data updating period
  this->period = cf->ReadInt(section, "period", 10);
  std::cout << "The data updating period is " << this->period << " seconds" << std::endl;

}


int BatteryDriver::Setup()
{
  puts("Battery driver initialising");

  // Retrieve the handle to the can device.
  if(!(this->can_dev = deviceTable->GetDevice(this->can_addr)))
  {
    PLAYER_ERROR("unable to locate suitable can device");
    return(-1);
  }

  // Subscribe my message queue to the can device.
  if(this->can_dev->Subscribe(this->InQueue) != 0)
  {
    PLAYER_ERROR("unable to subscribe to can device");
    return(-1);
  }

  puts("Battery driver ready");

  // Start the device thread; spawns a new thread and executes
  StartThread();

  return(0);
}


int BatteryDriver::Shutdown()
{
  puts("Shutting Battery driver down");

  // Stop and join the driver thread
  StopThread();

  // Unsubscribe from can
  this->can_dev->Unsubscribe(this->InQueue);

  puts("Battery driver has been shutdown");

  return(0);
}

I checked out some drivers you mentioned and I have already written some other drivers that do inter device subscription without any problem (usually subscribing to simulation interfaces, for Stage stuff). I will check out them again just in case. Thanks!

gazkune