Assembling an XBee API packet in PHP

In a previous post I showed how to parse an XBee API packet in C and PHP, for my project I needed both parsing and assembling of such packets. In case anyone would want to use it, here’s the PHP code for when you want to manipulate DIO pins.

function assemblePacket($module, $pin, $pinVal)
{
  $sum = 0; // checksum variable
  $packet = "<";
 
  if ($pinVal)
  { 
    $pinState = "05";
    $pinchk = 0x05;
  }
  else
  {
    $pinState = "04";
    $pinchk = 0x04;
  }
 
  $packet .= "7E"; // Start byte
  $packet .= "00"; // MSB length
  $packet .= "10"; // LSB length
 
  $packet .= "17"; // Remote AT command request
  $sum += 0x17;
  $packet .= "00"; // No response packet  
  $packet .= "00"; // 64bit address ignored Byte 1
  $packet .= "00"; // 64bit address ignored Byte 2
  $packet .= "00"; // 64bit address ignored Byte 3
  $packet .= "00"; // 64bit address ignored Byte 4
  $packet .= "00"; // 64bit address ignored Byte 5
  $packet .= "00"; // 64bit address ignored Byte 6
  $packet .= "00"; // 64bit address ignored Byte 7
  $packet .= "00"; // 64bit address ignored Byte 8
 
  $packet .= $module; // Module MSB and LSB
  $mbytes = str_split($module, 1);
  $sum += base_convert(getVal($mbytes[1]), 10, 16) + (base_convert(getVal($mbytes[0]), 10, 16) << 4);
  $sum += base_convert(getVal($mbytes[3]), 10, 16) + (base_convert(getVal($mbytes[2]), 10, 16) << 4); 
 
 
  $packet .= "02"; // Apply changes immediately
  $sum += 0x02;
  $packet .= "44"; // Character D in HEX
  $sum += 0x44;
  $packet .= (string)(30 + $pin); // Pin value, 0 in hex is 30
  $sum += dechex(30+$pin)+30;
  $packet .= $pinState; // Pinstate
  $sum += $pinchk;
  $checksum = 0xFF - ( $sum & 0xFF);
  $hack = str_split(dechex($checksum), 1);
  echo $hack[0];
  echo "     ";
  echo $hack[1];
  if(ctype_alpha($hack[0]))
    $packet .= strtoupper($hack[0]);
  else
    $packet .= $hack[0]; 
  if(ctype_alpha($hack[1]))
    $packet .= strtoupper($hack[1]);
  else
    $packet .= $hack[1];         
  $packet .= ">";
  return $packet;  
} 
 
function getVal($c)
{
   if($c >= '0' && $c <= '9')
     return ($c - '0');
   else
     return ($c-'A'+10);
}

You input the destination as a String, the pin as a number and the state as 0 or 1. Example:

$packet = assemblePacket("1337", 2, 1);

This would set pin DIO2 to high for the module with address 1337.

Update: Some things didn’t work before, especially if there were A-F values in the checksum, hence the dirty hack to get it to work. I know it’s not pretty but it works.