AREXPORT void ArServerInfoRobot::batteryInfo(ArServerClient *client, 
					     ArNetPacket *packet)
{
  ArNetPacket sending;

  myRobot->lock();
  if (myRobot->haveStateOfCharge())
  {
    // this is a temporary workaround since the config packet reader
    // in this aria doesn't get these values from the firmware
    if (myRobot->getStateOfChargeLow() <= 0 && 
	myRobot->getStateOfChargeShutdown() <= 0)
    {
      sending.doubleToBuf(20);
      sending.doubleToBuf(3);
    }
    else
    {
      sending.doubleToBuf(myRobot->getStateOfChargeLow());
      sending.doubleToBuf(myRobot->getStateOfChargeShutdown());
    }
    // voltage is really state of charge
    sending.uByteToBuf(1);
  }
  else
  {
    const ArRobotConfigPacketReader *reader;
    reader = myRobot->getOrigRobotConfig();
    if (reader != NULL && reader->hasPacketArrived())
    {
      if (reader->getLowBattery() != 0)
	sending.doubleToBuf(reader->getLowBattery() * .1);
      else
	sending.doubleToBuf(11.5);
      if (reader->getShutdownVoltage() != 0)
	sending.doubleToBuf(reader->getShutdownVoltage() * .1);
      else
	sending.doubleToBuf(11);
    }
    else
    {
      sending.doubleToBuf(11.5);
      sending.doubleToBuf(11);
    }
    // voltage is voltage, not state of charge
    sending.uByteToBuf(0);
  }
  
  myRobot->unlock();
  client->sendPacketTcp(&sending);

}
AREXPORT void ArHybridForwarderVideo::finishConstructor(void)
{
  myClient->lock();
  mySendVideoSizeCB = new ArFunctor2C<ArHybridForwarderVideo, ArServerClient*, 
  ArNetPacket *>(this, &ArHybridForwarderVideo::sendVideoSize);

  mySendVideoCB = new ArFunctor2C<ArHybridForwarderVideo, ArServerClient*, 
  ArNetPacket *>(this, &ArHybridForwarderVideo::sendVideo);
  
  myReceiveVideoSizeCB = new ArFunctor1C<ArHybridForwarderVideo, 
  ArNetPacket *>(this, &ArHybridForwarderVideo::receiveVideoSize);

  myReceiveVideoCB = new ArFunctor1C<ArHybridForwarderVideo, 
  ArNetPacket *>(this, &ArHybridForwarderVideo::receiveVideo);

  myClientCycleCB = new ArFunctorC<ArHybridForwarderVideo>(
	  this, &ArHybridForwarderVideo::clientCycleCallback);

  myReqSent = false;
  myLastReqSent.setToNow();
  myLastReceivedVideo.setToNow();
  myVideoRequestTime = 100;
  myForwardingVideo = false;

  if (myClient != NULL && myServer != NULL && myClient->isConnected())
  {
    myClient->addCycleCallback(myClientCycleCB);
    if (myClient->dataExists("videoSize"))
    {
      myServer->addData("videoSize", 
			"gets the width and height of the video data", 
			mySendVideoSizeCB, 
			"none", "uByte2: width, uByte2: height",
			"Video", "RETURN_SINGLE");
      myClient->addHandler("videoSize", myReceiveVideoSizeCB);
      myClient->requestOnce("videoSize");
    }
    if (myClient->dataExists("sendVideo"))
    {
      ArLog::log(ArLog::Normal, "Forwarding video.");
      myForwardingVideo = true;
      myClient->addHandler("sendVideo", myReceiveVideoCB);
      ArNetPacket packet;
      packet.uByteToBuf(90);
      myClient->requestOnce("sendVideo", &packet);

      myIsSendVideoAvailable = 
        myServer->addData("sendVideo", "gets video from the robot's camera (you should requestOnce this, you shouldn't request it, since you could easily fill the bandwidth that way)",
			                    mySendVideoCB, "uByte: quality (0 - 100)", 
			  "out: uByte2: width, uByte2: height, (len - readLen)*uByte: jpegData", "Video", "RETURN_VIDEO");
    }
  }
  myClient->unlock();
}
AREXPORT void ArServerInfoRobot::batteryInfo(ArServerClient *client, 
					     ArNetPacket *packet)
{
  ArNetPacket sending;

  myRobot->lock();
  if (myRobot->haveStateOfCharge())
  {
    sending.doubleToBuf(myRobot->getStateOfChargeLow());
    sending.doubleToBuf(myRobot->getStateOfChargeShutdown());
    // voltage is really state of charge
    sending.uByteToBuf(1);
  }
  else
  {
    const ArRobotConfigPacketReader *reader;
    reader = myRobot->getOrigRobotConfig();
    if (reader != NULL && reader->hasPacketArrived())
    {
      if (reader->getLowBattery() != 0)
	sending.doubleToBuf(reader->getLowBattery() * .1);
      else
	sending.doubleToBuf(11.5);
      if (reader->getShutdownVoltage() != 0)
	sending.doubleToBuf(reader->getShutdownVoltage() * .1);
      else
	sending.doubleToBuf(11);
    }
    else
    {
      sending.doubleToBuf(11.5);
      sending.doubleToBuf(11);
    }
    // voltage is voltage, not state of charge
    sending.uByteToBuf(0);
  }
  
  myRobot->unlock();
  client->sendPacketTcp(&sending);

}