Пример #1
0
short_code_action sendSIP_init(const char *imsi, const TLSubmit& submit,
                               const std::string &body, short_code_params *scp)
{
	const char *address = submit.DA().digits();
	const TLUserData& tl_ud = submit.UD();
	const char *from = scp->scp_qmsg_it->parsed->from->url->username;
	LOG(INFO) << "from " << imsi << " to " << address;

	if (scp == NULL)
	{
		LOG(WARN) << "short_code_params is NULL. Error.";
		return SCA_INTERNAL_ERROR;
	}

	// START OF THE SIP PROCESSING
	osip_message_t *omsg = scp->scp_qmsg_it->parsed;

	// Req.URI
	osip_free(omsg->req_uri->username);
	omsg->req_uri->username = (char *)osip_malloc (strlen(address)+1);
	strcpy(omsg->req_uri->username, address);

	// To:
	set_to_for_smsc(address, scp->scp_qmsg_it);

	// Let them know that parsed part has been changed.
	scp->scp_qmsg_it->parsed_was_changed();

	if (ISLOGGING(DEBUG)) {
		// Call make_text_valid() is needed for debug only.
		scp->scp_qmsg_it->make_text_valid();
		LOG(DEBUG) << "Updated SMS message: " << scp->scp_qmsg_it->text;
	}
	return SCA_RESTART_PROCESSING;
}
Пример #2
0
bool recode_tpdu(const std::string &body,
                 short_msg_p_list::iterator &smsg)
{
	bool return_action = true;

	// Safety check
	if (smsg->tl_message == NULL)
	{
		LOG(WARN) << "TLMessage is not available. Error during SMS decoding occurred?";
		return false;
	}

	switch ((TLMessage::MessageType)smsg->tl_message->MTI()) {
	case TLMessage::SUBMIT: {
		TLSubmit *submit = (TLSubmit*)smsg->tl_message;
		const TLUserData& tl_ud = submit->UD();
		create_sms_delivery(body, tl_ud, smsg);
		pack_tpdu(smsg);
		return_action = true;
		break;
	}

	case TLMessage::DELIVER_REPORT:
	case TLMessage::STATUS_REPORT:
		// TODO
		LOG(WARN) << "TPDU must be of SMS-SUBMIT type, we have MTI="
		          << (TLMessage::MessageType)smsg->tl_message->MTI();
		return false;
	}

	// Now we have MS->SC message
	smsg->ms_to_sc = false;

	return return_action;
}
Пример #3
0
TLMessage *SMS::parseTPDU(const TLFrame& TPDU, bool directionUplink)
{
	LOG(DEBUG) << "SMS: parseTPDU MTI=" << (TLMessage::MessageType)TPDU.MTI();
	if (directionUplink) {
	  // Handle just the uplink cases.
	  switch ((TLMessage::MessageType)TPDU.MTI()) {
		case TLMessage::DELIVER_REPORT:
		case TLMessage::STATUS_REPORT:
			// FIXME -- Not implemented yet.
			LOG(WARNING) << "Unsupported TPDU type: " << (TLMessage::MessageType)TPDU.MTI();
			return NULL;
		case TLMessage::SUBMIT: {
			TLSubmit *submit = new TLSubmit;
			submit->parse(TPDU);
			LOG(INFO) << "SMS SMS-SUBMIT " << *submit;
			return submit;
		}
		default:
			return NULL;
	  }
	} else {
	  switch ((TLMessage::MessageType)TPDU.MTI()) {
		// 10-2013: Pat added the DELIVER which is the downlink message so we can parse it for reporting purposes.
		case TLMessage::DELIVER: {
			TLDeliver *deliver = new TLDeliver(TPDU);
			return deliver;
		}
		default:
			LOG(WARNING) << "parsing unsupported TPDU type: " << (TLMessage::MessageType)TPDU.MTI();
			return NULL;
	  }
	}
}
Пример #4
0
/** Send a TPDU through whatever gateway is available.  */
short_code_action submitSMS(const char *imsi, const TLSubmit& submit,
                            const std::string &body, short_code_params *scp)
{
	LOG(INFO) << "from " << imsi << " message: " << submit;
	const TLAddress& address = submit.DA();

	// Check for direct e-mail address at start of message body.
	// FIXME -- This doesn't really follow the spec.  See GSM 03.40 3.8.
	static const Regexp emailAddress("^[[:graph:]]+@[[:graph:]]+ ");
	if (emailAddress.match(body.data())) {
		// FIXME -- Get the sender's E.164 to put in the subject line.
		char bodyCopy[body.length()+2];
		strcpy(bodyCopy,body.data());
		char* SMTPAddress = bodyCopy;
		char* term = strchr(bodyCopy,' ');
		// If term's NULL, the regexp is broken.
		assert(term);
		*term = '\0';
		char* SMTPPayload = term+1;
		LOG(INFO) << "sending SMTP to " << SMTPAddress << ": " << SMTPPayload;
		if (SMTPPayload) return sendEMail(SMTPAddress,SMTPPayload,"from OpenBTS gateway");
		else return sendEMail(SMTPAddress,"(empty)","from OpenBTS gateway");
	}

	// Send to smqueue or HTTP gateway, depending on what's defined in the config.
	if (gConfig.defines("SMS.HTTP.Gateway"))
		// If there is an external HTTP gateway, use it.
		return sendHTTP(address.digits(), body);
	else
		// Otherwise, we are looking for a SIP interface to smqueue.
		return sendSIP_init(imsi, submit, body, scp);
}
Пример #5
0
/**
	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;
	}
}
Пример #6
0
TLMessage *SMS::parseTPDU(const TLFrame& TPDU)
{
	LOG(DEBUG) << "SMS: parseTPDU MTI=" << TPDU.MTI();
	// Handle just the uplink cases.
	switch ((TLMessage::MessageType)TPDU.MTI()) {
		case TLMessage::DELIVER_REPORT:
		case TLMessage::STATUS_REPORT:
			// FIXME -- Not implemented yet.
			LOG(WARNING) << "Unsupported TPDU type: " << (TLMessage::MessageType)TPDU.MTI();
			return NULL;
		case TLMessage::SUBMIT: {
			TLSubmit *submit = new TLSubmit;
			submit->parse(TPDU);
			LOG(INFO) << "SMS SMS-SUBMIT " << *submit;
			return submit;
		}
		default:
			return NULL;
	}
}
Пример #7
0
/** Send a TPDU through whatever gateway is available.  */
short_code_action submitSMS(const char *imsi, const TLSubmit& submit,
                            const std::string &body, short_code_params *scp)
{
	LOG(INFO) << "from " << imsi << " message: " << submit;
	const TLAddress& address = submit.DA();

//#if 0
//This is broken under Unbuntu becasue of changes in the "mail" program.

	// Check for direct e-mail address at start of message body.
	// FIXME -- This doesn't really follow the spec.  See GSM 03.40 3.8.
	static const Regexp emailAddress("^[[:graph:]]+@[[:graph:]]+ ");
	if (emailAddress.match(body.data())) {
		char bodyCopy[body.length()+2];
		strcpy(bodyCopy,body.data());
		char* SMTPAddress = bodyCopy;
		char* term = strchr(bodyCopy,' ');
		// If term's NULL, the regexp emailAddress is broken.
		assert(term);
		*term = '\0';
		char* SMTPPayload = term+1;
		// Get the sender's E.164 to put in the subject line.
		char* clid = scp->scp_smq->my_hlr.getCLIDLocal(imsi);
		char subjectLine[200];
		if (!clid) sprintf(subjectLine,"from %s",imsi);
		else {
			sprintf(subjectLine,"from %s",clid);
			free(clid);
		}
		// Send it.
		LOG(INFO) << "sending SMTP to " << SMTPAddress << ": " << SMTPPayload;
		if (SMTPPayload) return sendEMail(SMTPAddress,SMTPPayload,subjectLine);
		else return sendEMail(SMTPAddress,"(empty)","from OpenBTS gateway");
	}
//#endif

	char* destinationNumber = scp->scp_smq->my_hlr.getIMSI2(address.digits());

	// Send to smqueue or HTTP gateway, depending on what's defined in the config.
	// And whether of not we can resolve the destination, and a global relay does not exist,
	// AND the message is not to a shortcode.
	if (gConfig.getStr("SIP.GlobalRelay.IP").length() == 0 && gConfig.getStr("SMS.HTTPGateway.URL").length() != 0 &&
		!destinationNumber)
		// If there is an external HTTP gateway, use it.
		return sendHTTP(address.digits(), body);

	free(destinationNumber);
	return sendSIP_init(imsi, submit, body, scp);
}
Пример #8
0
/**
	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;
	}
}