void RPMessage::write(RLFrame& dest) const { // All relay-layer messages (GSM 04.11 7.3) have the same 2-byte header. dest.resize(bitsNeeded()); size_t wp=0; dest.writeField(wp,0,5); // Note that we add one for the n->ms direction. // See GSM 04.11 8.2.2 Table 8.3 dest.writeField(wp,MTI()+1,3); dest.writeField(wp,mReference,8); // After the header, fill in the body. writeBody(dest,wp); }
void RPMessage::parse(const RLFrame& frame) { size_t rp = 8; // FIXME -- A consistency check of PD and MTI would be good. mReference = frame.readField(rp,8); parseBody(frame,rp); }
/** Process the RPDU. @param mobileID The sender's IMSI. @param RPDU The RPDU to process. @return true if successful. */ bool handleRPDU(const L3MobileIdentity& mobileID, const RLFrame& RPDU) { LOG(DEBUG) << "SMS: handleRPDU MTI=" << RPDU.MTI(); switch ((RPMessage::MessageType)RPDU.MTI()) { case RPMessage::Data: { ostringstream body; RPDU.hex(body); return sendSIP(mobileID, gConfig.getStr("SIP.SMSC"), body.str().data()); } case RPMessage::Ack: case RPMessage::SMMA: return true; case RPMessage::Error: default: return false; } }
/** Process the RPDU. @param mobileID The sender's IMSI. @param RPDU The RPDU to process. @return true if successful. */ bool handleRPDU(TransactionEntry *transaction, const RLFrame& RPDU) { LOG(DEBUG) << "SMS: handleRPDU MTI=" << RPDU.MTI(); switch ((RPMessage::MessageType)RPDU.MTI()) { case RPMessage::Data: { string contentType = gConfig.getStr("SMS.MIMEType"); ostringstream body; if (contentType == "text/plain") { // TODO: Clean this mess up! RPData data; data.parse(RPDU); TLSubmit submit; submit.parse(data.TPDU()); body << submit.UD().decode(); } else if (contentType == "application/vnd.3gpp.sms") { RPDU.hex(body); } else { LOG(ALERT) << "\"" << contentType << "\" is not a valid SMS payload type"; } const char* address = NULL; if (gConfig.defines("SIP.SMSC")) address = gConfig.getStr("SIP.SMSC").c_str(); /* The SMSC is not defined, we are using an older version */ if (address == NULL) { RPData data; data.parse(RPDU); TLSubmit submit; submit.parse(data.TPDU()); address = submit.DA().digits(); } return sendSIP(transaction, address, body.str().data(),contentType.c_str()); } case RPMessage::Ack: case RPMessage::SMMA: return true; case RPMessage::Error: default: return false; } }
/** Process the incomming RPDU. @param mobileID The sender's IMSI. @param RPDU The RPDU to process. @return true if successful. */ bool MOSMSMachine::handleRPDU(const RLFrame& RPDU) { LOG(DEBUG) << "SMS: handleRPDU MTI=" << RPDU.MTI(); switch ((RPMessage::MessageType)RPDU.MTI()) { case RPMessage::Data: { string contentType = gConfig.getStr("SMS.MIMEType"); ostringstream body; string toAddress = ""; if (contentType == "text/plain") { RPData data; data.parse(RPDU); TLSubmit submit; submit.parse(data.TPDU()); body << submit.UD().decode(); // (pat) TODO: efficiencize this. toAddress = string(submit.DA().digits()); } else if (contentType == "application/vnd.3gpp.sms") { toAddress = "smsc"; // If encoded this is expected in destination address RPDU.hex(body); } else { LOG(ERR) << "\"" << contentType << "\" is not a valid SMS payload type"; } // Steps: // 1 -- Complete transaction record. // 2 -- Send TL-SUBMIT to the server. // 3 -- Wait for response or timeout. // 4 -- Return true for OK or ACCEPTED, false otherwise. // Step 1 and 2 -- Complete the transaction record and send TL-SUMBIT to server. // Form the TLAddress into a CalledPartyNumber for the transaction. // Attach calledParty and message body to the transaction. SipDialog::newSipDialogMOSMS(tran()->tranID(), tran()->subscriber(), toAddress, body.str(), contentType); return true; } case RPMessage::Ack: case RPMessage::SMMA: return true; case RPMessage::Error: default: return false; } }