Arduino + XBee (S1) in API Not Echoing Properly

Setup:
A - XBee (series 1, ID=1234, MY=1111, AP=2, CE=1) connected via a USB explorer to a computer (Windows)

B - XBee (series 1, ID=1234, MY=2222, AP=2, CE=0) connected to an Arduino Pro Mini (3.3V, 8MHz) via the hardware TX/RX pins. There is an h-bridge coupled to the ProMini that drives a motor forward or reverse based on the signals received through the XBee.

When I had these in AT mode (AP=0), I had full functionality. I could send a command from either X-CTU or a Visual Basic GUI I wrote and the motor attached to the ProMini would behave properly. But I want to have several of these units, and to be able to address them individually instead of as a whole, so I started down the API route. I have communication working, in that I can send a frame through X-CTU to the target XBee and a proper reply appears in the X-CTU console.

I tried writing a sketch that as a start point would merely echo a received payload back to the computer (after confirming all looked good here I will go to work on processing the payload to get the h-bridge to operate accordingly). However, it echos back different values than what I sent.

sent (via X-CTU):
7E 00 0A 01 01 22 22 00 3C 30 30 30 3E AF (essentially the payload is the character string '<000>')

received (in X-CTU) (I broke up the two response frames for readability):
7E 00 03 89 01 00 75 (success message)
7E 00 0A 81 22 22 36 00 53 49 20 52 56 A0 (payload received from unit 2222 is 53 49 20 52 56, or the character string 'SI RV' - a space in there of course)

I'm probably missing something obvious here. But I naturally need to be able to process the correct data to get my motor to behave properly down the line. The sketch:

#include <XBee.h>

XBee xbee = XBee();
XBeeResponse response = XBeeResponse();
Rx16Response rx16 = Rx16Response();

const int motorAPin1 = 12;    // H-bridge motor control output FIN (pin 3)
const int motorAPin2 = 11;    // H-bridge motor control output RIN (pin 5)

uint8_t data[5];

void setup()
{
  Serial.begin(38400);  // initialize xbee serial communications
  xbee.setSerial(Serial);
}

void loop()
{
  xbee.readPacket();
  
  if (xbee.getResponse().isAvailable()) {
    // got something
    
    if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
      // got an RX16 response
      for (int i = 0; i<5; i++)
      {
        data[i] = rx16.getData(i);
      }
      
      Tx16Request tx = Tx16Request(0x1111, data, sizeof(data));
      xbee.send(tx);
    }
  }
}

If instead of sending the data[] array from the rx16.getData call I use

for (int i = 0;i<5;i++)
{
  data[i] = 31;
}

I get 1F in my payload response in X-CTU which is decimal 31, so that makes some sense I guess. But before I wasn't even getting the same value for the middle three bytes of the payload which suggests this is more than a matter of me messing up hex vs decimal and all that.

My motor control code ultimately does a switch-case based on a number 0-107, so I will probably change my payload structure sent from the computer to be a single byte (versus 5, especially since with the API mode I can verify I am getting a full packet and not just random crap) that on the Arduino I will convert hex -> decimal and then use accordingly, as opposed to the tokenized 5-character string structure I was using (<000> - <107> so I made sure I wasn't getting garbage, legacy from when I was controlling the motor through direct serial), but first I need to sort out what is going on here.

Let me try what is hopefully a simpler question. When Arduino receives a hex string through serial (in this case from the XBee), how does it handle it? Does it automatically convert it to something else internally (byte characters perhaps?), do I need to do that, or what?

I tried changing the payload I was sending to the Arduino+XBee to have only one byte of information (for example, 6B), and echo that back by reading data[0]=rx16.getData(0) and sending that back to the originating XBee, but I get 0x53 back, seemingly regardless of what I send in the original payload (I only tried a couple values mind you, but it was consistent...).

What am I missing please?

More information. Hopefully someone has an answer as to what is going on?

In the originally-posted code, if I replace

Tx16Request tx = Tx16Request(0x1111, data, sizeof(data));

with

Tx16Request tx = Tx16Request(0x1111, rx16.getData(), sizeof(rx16.getData()));

The XBee connected to the computer will ALWAYS receive {53,49} back in X-CTU as the payload from the XBee connected to the Arduino. It doesn't matter if I send one byte or 5 bytes from X-CTU, it will always receive back those same 2 bytes as the payload (along with the rest of the usual packet information).

Example:
From X-CTU, I send {7E,00,0A,01,01,22,22,00,4F,30,30,30,4F,8B}.
The XBee connected to the Arduino receives this information fine.
In X-CTU, I see as a response 2 frames:
{7E,00,03,89,01,00,75} -> usual received OK command
{7E,00,07,81,22,22,35,00,53,49,69} -> payload is {53,49}, was expecting {4F,30,30,30,4F}

This is the case even if I send one byte of payload from X-CTU, 3 bytes, or whatever.

The plot thickens. I really need to get this working, so please, if anyone has ANY idea, please speak up. I'm beginning to wonder if there is a bug in the xbee library, which seems unlikely given I'm not the only one using it...

Using this code on an Uno for now for simplicity:

#include <XBee.h>
#include <SoftwareSerial.h>

SoftwareSerial softSer(8,9);

XBee xbee = XBee();
XBeeResponse response = XBeeResponse();
Rx16Response rx16 = Rx16Response();

void setup()
{
  Serial.begin(38400);  // initialize USB serial communications
  softSer.begin(38400); // initialize software serial for the XBee
  xbee.setSerial(softSer);
}

void loop()
{
  xbee.readPacket();
  
  if (xbee.getResponse().isAvailable()) {
    // got something
    
    if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
      // got an RX16 response
      Tx16Request tx = Tx16Request(0x1111, rx16.getData(), sizeof(rx16.getData())); // echo the payload back
      xbee.send(tx);
      //Serial.println(sizeof(rx16.getData()));
      Serial.println(rx16.getData(0),HEX);
    }
  }
}

If I send the packet 7E 00 06 01 01 22 22 00 44 75 (payload of 0x44 to MY 2222) through X-CTU, I see 7E 00 07 81 22 22 28 00 E7 3D EE as the echoed packet (payload of 0xE7 0xEE from MY 2222). I receive that same payload back no matter what I send for the payload, no matter how many bytes. WTF???

I swapped for a different Uno. The returned payload is still always 2 bytes as well, though a different 2 bytes. So, coupled with the Pro Mini I was originally finding this with, I consistently have a 2-byte payload always echoed, though the specific 2 bytes differs from Arduino to Ardunio. Huh?

So, I turned off the xbee library and had it spit out the entire packet byte by byte to the serial monitor:

#include <SoftwareSerial.h>

SoftwareSerial xbee(8,9);

byte tempChar;

void setup()
{ 
  xbee.begin(38400);  // initialize xbee serial communications
  Serial.begin(38400);
}

void loop()
{
  if (xbee.available())
  {
    delay(50);  // brief delay to allow a full command series to come in before processing - probably not needed in this code!

    tempChar = xbee.read();
    
    Serial.println(tempChar,HEX);
  }
}

Send the packet 7E 00 06 01 01 22 22 00 44 75 through X-CTU. And low and behold, the data in the serial monitor looks right! It is: 7E 00 06 81 7D 31 7D 31 2F 00 44 E9. Since the sender was ID 1111, the xbee had to escape the ID, so 0x7D 0x31 apparently is equivalent to 0x11. I need to read some more to fully understand that, I guess some math is going on with the actual 0x11 byte to net 0x31. But the main point is the payload is there correctly. Similar result if I send a 5-byte payload.

Incidentally, I did change the xbee with ID 1111 to 0101 to see if the escaping was causing a problem with the library processing, but no joy. Still the same 2-byte payload returned at all times.

So I ask again, WTF? Am I missing something or is the xbee library broken? I guess if I have to I can write a frame parser for my application, but I'd rather not.