When we got back from Burning Man this year we received a few instances of a really interesting bug report. It goes like this: "My friend X and I texted each other on the playa with your system, but now that we are back home, we can't text each other anymore. Texts to and from other people still work. We both have iPhones." After some head-scratching, I recommended a brute-force fix: "Delete all of the messages you exchanged through our system at Burning Man." It worked.
So what happened? When you receive or send a text message via SMS, it has two E.164 addresses. One address, in layer 5, is the mobile phone number of the subscriber sending or receiving the message. The other address, in layer 4, is the SMSC that processes the text message. (SMSCs are to text messages what SMTP servers are to e-mail, and they have E.164 addresses just like telephones.) Normally, the SMSC address for your outgoing text messages is set by your carrier. In some phones, you can also override the carrier's SMSC address and provide one of your own. Here's my working theory: It appears that certain models of iPhone, under some set of conditions, remember the SMSC addresses from which you received a text message and then use that SMSC address for future outbound messages. When you send a text to a given person, these iPhones appear to send the outbound message through the same SMSC used for the most recent message received from that person, or, possibly, the SMSC address used for an error message associated with an attempt to send to that person. Since the OpenBTS system doesn't have a real SMSC address, we were just filling in the SMSC address field in the L4 header with a fake number. When people got home, these iPhones continued to use this fake SMSC address to send texts to anyone from whom they received text messages through our network. Those send attempts failed. When they deleted the messages with the fake SMSC address, everything worked normally again.
So what do we do to prevent this? One solution would be to stick a known SMSC address into the L4 header, instead of the fake one, but that might have unexpected effects of its own. A better solution is to preserve the L4 SMSC address end-to-end, even though we don't use it, which is what we will do in the future.
Live and learn. It is interesting to know, though, that you can use a BTS tool like OpenBTS or OpenBSC to control SMSC settings in a closed device like the iPhone. That probably deserves more investigation.