/** 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; } }
// Return true on success. bool MTSMSMachine::createRPData(RPData &rp_data) { // TODO: Read MIME Type from smqueue!! const char *contentType = tran()->mContentType.c_str(); PROCLOG(DEBUG)<<LOGVAR(contentType)<<LOGVAR(tran()->mMessage); if (strncmp(contentType,"text/plain",10)==0) { TLAddress tlcalling = TLAddress(tran()->calling().digits()); TLUserData tlmessage = TLUserData(tran()->mMessage.c_str()); PROCLOG(DEBUG)<<LOGVAR(tlcalling)<<LOGVAR(tlmessage); rp_data = RPData(this->mRpduRef, RPAddress(gConfig.getStr("SMS.FakeSrcSMSC").c_str()), TLDeliver(tlcalling,tlmessage,0)); } else if (strncmp(contentType,"application/vnd.3gpp.sms",24)==0) { BitVector2 RPDUbits(strlen(tran()->mMessage.c_str())*4); if (!RPDUbits.unhex(tran()->mMessage.c_str())) { LOG(WARNING) << "Message is zero length which is valid"; // This is valid continue return true; } try { // I suspect this is here to catch the above FIXED crash when string is zero length RLFrame RPDU(RPDUbits); LOG(DEBUG) << "SMS RPDU: " << RPDU; rp_data.parse(RPDU); LOG(DEBUG) << "SMS RP-DATA " << rp_data; } catch (SMSReadError) { LOG(WARNING) << "SMS parsing failed (above L3)"; // Cause 95, "semantically incorrect message". //LCH->l2sendf(CPData(L3TI,RPError(95,this->mRpduRef)),3); if you ever use this, it should call l3sendSms return false; } catch (GSM::L3ReadError) { LOG(WARNING) << "SMS parsing failed (in L3)"; // TODO:: send error back to the phone return false; } catch (...) { LOG(ERR) << "Unexpected throw"; // cryptic, but should never happen. return false; } } else { LOG(WARNING) << "Unsupported content type (in incoming SIP MESSAGE) -- type: " << contentType; return false; } return true; }
/** 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; } }