/*
 * Result of query for buddy with given username and serviceName
 *
 * If the buddy is found, we can send no matter what. If buddy is not found, we need to check if this service allows sending IM messages
 * to non buddies (gtalk does not allow this, aol does)
 */
MojErr SendOneMessageHandler::findBuddyResult(MojObject& result, MojErr findErr)
{

	if (findErr) {

		MojString error;
		MojErrToString(findErr, error);
		MojLogError(IMServiceApp::s_log, _T("findBuddyResult: error %d - %s"), findErr, error.data());
		// not much we can do here...
		failMessage(ERROR_SEND_GENERIC_ERROR);

	} else {

		// log the results
		MojString mojStringJson;
		result.toJson(mojStringJson);
		MojLogDebug(IMServiceApp::s_log, _T("findBuddyResult result: %s"), mojStringJson.data());

		// "results" in result
		MojObject results;
		result.get(_T("results"), results);

		// check to see if array is empty - there should really always be 0 or 1 item here
		if (!results.empty()){

			// buddy is on the list - send to the transport
			MojLogInfo(IMServiceApp::s_log, _T("findBuddyResult - user is on buddy list. No need to check account template."));
			sendToTransport();
		}
		else {
			MojLogInfo(IMServiceApp::s_log, _T("findBuddyResult - no buddy found. Need to check account template if this is allowed"));

			// check palm://com.palm.service.accounts/listAccountTemplates {"capability":"MESSAGING"} to get a list of account templates that support messaging.
			// If the account template includes "chatWithNonBuddies":false, it should fail to send.
			MojLogInfo(IMServiceApp::s_log, "Issuing listAccountTemplates request to com.palm.service.accounts");

			// parameters: {“capability”:”MESSAGING”}
			MojObject params;
			params.putString("capability", "MESSAGING");

			// Get a request object from the service
			MojRefCountedPtr<MojServiceRequest> req;
			MojErr err = m_service->createRequest(req);

			if (!err) {
				err = req->send(m_listAccountSlot, "com.palm.service.accounts", "listAccountTemplates", params);
			}

			if (err) {
				MojString error;
				MojErrToString(err, error);
				MojLogError(IMServiceApp::s_log, _T("findBuddyResult failed to send request to accounts: error %d - %s"), err, error.data());
				// not much we can do here...don't leave message still pending
				failMessage(ERROR_SEND_GENERIC_ERROR);
			}
		}
	}

	return MojErrNone;
}
// Expected responses
// {"activityId":78,"returnValue":true}
// {"activityId":78,"event":"start","returnValue":true}  <-- this occurs when the timeout fires
// Error in case there is already an activity for the given serviceName
// {"errorCode":17,"errorText":"Activity with that name already exists","returnValue":false}
MojErr ConnectionState::ConnectionChangedScheduler::scheduleActivityResult(MojObject& result, MojErr err)
{
	// log the parameters
	IMServiceHandler::logMojObjectJsonString(_T("ConnectionChangedScheduler::scheduleActivityResult: %s"), result);

	if (MojErrNone != err) {
		MojString error;
		MojErrToString(err, error);
		MojLogError(IMServiceApp::s_log, _T("ConnectionChangedScheduler::scheduleActivityResult failed: error %d - %s"), err, error.data());
		// we created this slot with unlimited responses, so we have to explicitly cancel it, unless there is another activity of this name already, in which case
		// we get here again
		if (MojErrExists != err) { // err 17 = "Activity with that name already exists"
			m_scheduleActivitySlot.cancel();
		}
	}
	else {
		MojString event;
		if (result.getRequired(_T("event"), event) == MojErrNone)
		{
			MojLogInfo(IMServiceApp::s_log, _T("ConnectionChangedScheduler::scheduleActivityResult event=%s"), event.data());
			if (event == "start")
			{
				MojInt64 activityId = 0;
				MojObject dummy;
				m_loginState->handleConnectionChanged(dummy);

				bool found = result.get("activityId", activityId);
				if (found && activityId > 0)
				{
					MojRefCountedPtr<MojServiceRequest> req;
					err = m_service->createRequest(req);
					MojObject completeParams;
					completeParams.put(_T("activityId"), activityId);
					err = req->send(m_activityCompleteSlot, "com.palm.activitymanager", "complete", completeParams, 1);
				}
				else {
					MojLogError(IMServiceApp::s_log,_T("ConnectionChangedScheduler::scheduleActivityResult - missing activityId"));
				}
				if (activityId <= 0 || err) {
					MojString error;
					MojErrToString(err, error);
					MojLogError(IMServiceApp::s_log, _T("ConnectionChangedScheduler::scheduleActivityResult send request failed: error %d - %s"), err, error.data());
					// we created this slot with unlimited responses, so we have to explicitly cancel
					m_scheduleActivitySlot.cancel();
				}
			}
		}
		// if there is no event we get here again
	}

	return MojErrNone;
}
/*
 * New incoming IM message
 */
bool IMServiceHandler::incomingIM(const char* serviceName, const char* username, const char* usernameFrom, const char* message)
{

	MojLogTrace(IMServiceApp::s_log);

	// log the parameters
	// don't log the message text
	MojLogInfo (IMServiceApp::s_log, _T("incomingIM - IM received. serviceName: %s username: %s usernameFrom: %s"), serviceName, username, usernameFrom);

	// no error - process the IM
	MojRefCountedPtr<IMMessage> imMessage(new IMMessage);

	// set the message fields based on the incoming parameters
	MojErr err = imMessage->initFromCallback(serviceName, username, usernameFrom, message);

	if (!err) {
		// handle the message
		MojRefCountedPtr<IncomingIMHandler> incomingIMHandler(new IncomingIMHandler(m_service));
		err = incomingIMHandler->saveNewIMMessage(imMessage);
	}
	if (err) {
		MojString error;
		MojErrToString(err, error);
		MojLogError(IMServiceApp::s_log, _T("incomingIM failed: %d - %s"), err, error.data());
		MojErrCheck(err);
		return false;
	}

	return true;
}
MojErr OnEnabledHandler::getAccountConfigResult(MojObject& payload, MojErr err)
{
    MojLogTrace(IMServiceApp::s_log);

    if (err != MojErrNone) {
        MojString error;
        MojErrToString(err, error);
        MojLogCritical(IMServiceApp::s_log, "getAccountConfig failed: error %d - %s", err, error.data());
    }
    else
    {
        MojObject results;
        payload.get("results", results);

        if (!results.empty())
        {
            m_config = *results.arrayBegin();
        }
    }

	if (m_enable) {
		err = accountEnabled();
	} else {
		err = accountDisabled();
	}

	return err;
}
/*
 * Result of query for loginState entry with given username and serviceName when removing a buddy
 *
 * Remove buddy from buddyStatus and contact DB
 */
MojErr SendOneMessageHandler::findAccountIdResult(MojObject& result, MojErr findErr)
{

	if (findErr) {

		MojString error;
		MojErrToString(findErr, error);
		MojLogError(IMServiceApp::s_log, _T("findAccountIdResult failed: error %d - %s"), findErr, error.data());
		// not much we can do here...
		failMessage(ERROR_SEND_GENERIC_ERROR);

	} else {

		// parse out the accountId
		readAccountIdFromResults(result);

		if (!m_accountId.empty()){

			// construct our where clause - find by username, accountId and servicename
			MojDbQuery query;
			query.where("username", MojDbQuery::OpEq, m_usernameTo);
			query.where("accountId", MojDbQuery::OpEq, m_accountId);
			query.from(IM_BUDDYSTATUS_KIND);
			MojObject queryObject;
			query.toObject(queryObject);
			IMServiceHandler::logMojObjectJsonString(_T("findAccountIdResult - buddyStatus query: %s"), queryObject);

			// call find
			//virtual MojErr find(Signal::SlotRef handler, const MojDbQuery& query,
			//					bool watch = false, bool returnCount = false) = 0;
			MojErr err = m_tempdbClient.find(this->m_findBuddySlot, query, /* watch */ false );
			if (err) {
				MojString error;
				MojErrToString(err, error);
				MojLogError(IMServiceApp::s_log, _T("findAccountIdResult dbClient.find() failed: error %d - %s"), err, error.data());
				failMessage(ERROR_SEND_GENERIC_ERROR);
			}
		}
		else {
			MojLogError(IMServiceApp::s_log, _T("findAccountIdResult: no matching loginState record found for %s"), m_serviceName.data());
			// tell the outgoing Command handler we are done
			failMessage(ERROR_SEND_GENERIC_ERROR);
		}
	}

	return MojErrNone;
}
/*
 * Result of query for loginState entry with given username and serviceName when adding a buddy
 *
 * Save buddy in buddyStatus and contact DB
 */
MojErr SendOneCommandHandler::findAccountIdForAddResult(MojObject& result, MojErr findErr)
{

	if (findErr) {

		MojString error;
		MojErrToString(findErr, error);
		MojLogError(IMServiceApp::s_log, _T("findAccountIdResult failed: error %d - %s"), findErr, error.data());

	} else {

		// parse out the accountId
		readAccountIdFromResults(result);

		if (!m_accountId.empty()){
			MojObject buddyStatus;
			buddyStatus.putString("_kind", IM_BUDDYSTATUS_KIND);
			buddyStatus.put("accountId", m_accountId);
			buddyStatus.put("username", m_buddyName);
			buddyStatus.put("serviceName", m_serviceName);

			// log it
			MojString json;
			buddyStatus.toJson(json);
			MojLogInfo(IMServiceApp::s_log, _T("saving buddy status to db: %s"), json.data());

			// save it
			// the save generates a call to the save result handler
			MojErr err = m_tempdbClient.put(m_addBuddySlot, buddyStatus);
			if (err) {
				MojString error;
				MojErrToString(err, error);
				MojLogError(IMServiceApp::s_log, _T("findAccountIdResult: dbClient.put() failed: error %d - %s"), err, error.data());
				// tell the outgoing Command handler we are done
				m_outgoingIMHandler->messageFinished();
			}
		}
		else {
			MojLogError(IMServiceApp::s_log, _T("findAccountIdResult: no matching loginState record found for %s %s"), m_username.data(), m_serviceName.data());
			// tell the outgoing Command handler we are done
			m_outgoingIMHandler->messageFinished();
		}
	}

	return MojErrNone;
}
Example #7
0
MojErr MojServiceMessage::replyError(MojErr code)
{
	MojString str;
	MojErr err = MojErrToString(code, str);
	MojErrCheck(err);
	err = replyError(code, str);
	MojErrCheck(err);

	return MojErrNone;
}
/*
 * Result of query for loginState entry with given username and serviceName when removing a buddy
 *
 * Remove buddy from buddyStatus and contact DB
 */
MojErr SendOneCommandHandler::findAccountIdForRemoveResult(MojObject& result, MojErr findErr)
{

	if (findErr) {

		MojString error;
		MojErrToString(findErr, error);
		MojLogError(IMServiceApp::s_log, _T("findAccountIdResult failed: error %d - %s"), findErr, error.data());

	} else {

		// parse out the accountId
		readAccountIdFromResults(result);

		if (!m_accountId.empty()){

			// construct our where clause - find by username, accountId and servicename
			MojDbQuery query;
			query.where("username", MojDbQuery::OpEq, m_buddyName);
			query.where("accountId", MojDbQuery::OpEq, m_accountId);
			query.from(IM_BUDDYSTATUS_KIND);

			// call del
			// virtual MojErr del(Signal::SlotRef handler, const MojDbQuery& query,
			//					   MojUInt32 flags = MojDb::FlagNone);
			MojErr err = m_tempdbClient.del(m_removeBuddySlot, query);
			if (err) {
				MojString error;
				MojErrToString(err, error);
				MojLogError(IMServiceApp::s_log, _T("removeBuddy: dbClient.del() failed: error %d - %s"), err, error.data());
				// tell the outgoing Command handler we are done
				m_outgoingIMHandler->messageFinished();
			}
		}
		else {
			MojLogError(IMServiceApp::s_log, _T("findAccountIdResult: no matching loginState record found for %s %s"), m_username.data(), m_serviceName.data());
			// tell the outgoing Command handler we are done
			m_outgoingIMHandler->messageFinished();
		}
	}

	return MojErrNone;
}
MojErr OnEnabledHandler::deleteImBuddyStatusResult(MojObject& payload, MojErr err)
{
	MojLogTrace(IMServiceApp::s_log);
	if (err != MojErrNone) {
		MojString error;
		MojErrToString(err, error);
		MojLogCritical(IMServiceApp::s_log, _T("deleteImBuddyStatusResult failed: error %d - %s"), err, error.data());
	}
	return err;
}
/*
 * Callback for DB delete results
 * deleted buddyStatus record
 */
MojErr SendOneCommandHandler::removeBuddyResult(MojObject& result, MojErr delErr)
{
	MojLogTrace(IMServiceApp::s_log);

	if (delErr) {
		MojString error;
		MojErrToString(delErr, error);
		MojLogError(IMServiceApp::s_log, _T("removeBuddyResult failed. error %d - %s"), delErr, error.data());
	}
	else {
		MojString json;
		result.toJson(json);
		MojLogInfo(IMServiceApp::s_log, _T("removeBuddyResult response: %s"), json.data());
	}

	// now delete from contacts DB
	//construct our where clause - find by username and servicename
	MojDbQuery query;
	MojErr err;
	err = createContactQuery(query);

	if (err) {
		MojString error;
		MojErrToString(err, error);
		MojLogError(IMServiceApp::s_log, _T("removeBuddyResult: createContactsQuery failed: error %d - %s"), err, error.data());
	}

	// call del
	// virtual MojErr del(Signal::SlotRef handler, const MojDbQuery& query,
	//					   MojUInt32 flags = MojDb::FlagNone);
	err = m_dbClient.del(this->m_removeContactSlot, query);
	if (err) {
		MojString error;
		MojErrToString(err, error);
		MojLogError(IMServiceApp::s_log, _T("removeBuddyResult: dbClient.del() failed: error %d - %s"), err, error.data());
		// tell the outgoing Command handler we are done
		m_outgoingIMHandler->messageFinished();
	}
	return MojErrNone;
}
MojErr OnEnabledHandler::addImLoginStateResult(MojObject& payload, MojErr err)
{
	MojLogTrace(IMServiceApp::s_log);

	if (err != MojErrNone) {
		MojString error;
		MojErrToString(err, error);
		MojLogCritical(IMServiceApp::s_log, _T("addLoginStateResult failed: error %d - %s"), err, error.data());
		//TODO retry adding the record. Not worrying about this for now because the add would only fail in
		// extreme conditions.
	}
	return err;
}
/**
 * callback from the save message call.
 */
MojErr IncomingIMHandler::IMSaveMessageResult(MojObject& result, MojErr saveErr)
{
	MojLogTrace(IMServiceApp::s_log);

	if (saveErr) {
		MojString error;
		MojErrToString(saveErr, error);
		MojLogError(IMServiceApp::s_log, _T("database put failed. error %d - %s"), saveErr, error.data());
	}
	else {
		IMServiceHandler::logMojObjectJsonString(_T("database put success: %s"), result);
	}

	return MojErrNone;
}
Example #13
0
	MojErr formatErrResponse(MojErr errExpected, MojObject& objOut)
	{
		MojString errTxt;
		MojErr err = MojErrToString(errExpected, errTxt);
		MojTestErrCheck(err);

		// format expected error return
		err = objOut.putBool(MojServiceMessage::ReturnValueKey, false);
		MojErrCheck(err);
		err = objOut.putInt(MojServiceMessage::ErrorCodeKey, (MojInt64)errExpected);
		MojErrCheck(err);
		err = objOut.putString(MojServiceMessage::ErrorTextKey, errTxt);
		MojErrCheck(err);

		return MojErrNone;
	}
MojErr IMServiceHandler::onEnabled(MojServiceMessage* serviceMsg, const MojObject payload)
{
	MojRefCountedPtr<OnEnabledHandler> handler(new OnEnabledHandler(m_service));
	MojErr err = handler->start(payload);
	if (err == MojErrNone) {
		serviceMsg->replySuccess();
	} else {
		MojString error;
		MojString msg;
		MojErrToString(err, error);
		msg.format(_T("OnEnabledHandler.start() failed: error %d - %s"), err, error.data());
		MojLogError(IMServiceApp::s_log, _T("%s"), msg.data());

		serviceMsg->replyError(err);
	}
	return MojErrNone;
}
/*
 * Callback for DB save results
 *
 * Status change to "waiting-for-connection"
 */
MojErr SendOneCommandHandler::imSaveCommandResult(MojObject& result, MojErr saveErr)
{
	MojLogTrace(IMServiceApp::s_log);

	if (saveErr) {
		MojString error;
		MojErrToString(saveErr, error);
		MojLogError(IMServiceApp::s_log, _T("save imcommand failed. error %d - %s"), saveErr, error.data());
	}
	else {
		MojString json;
		result.toJson(json);
		MojLogInfo(IMServiceApp::s_log, _T("save imcommand %s. response: %s"), this->m_currentCmdDbId.data(), json.data());
	}

	return MojErrNone;
}
/**
 * Callback from the save buddy in contact DB call.
 */
MojErr SendOneCommandHandler::addContactResult(MojObject& result, MojErr saveErr)
{
	MojLogTrace(IMServiceApp::s_log);

	if (saveErr) {
		MojString error;
		MojErrToString(saveErr, error);
		MojLogError(IMServiceApp::s_log, _T("addContactResult failed. error %d - %s"), saveErr, error.data());
	}
	else {
		IMServiceHandler::logMojObjectJsonString(_T("addContactResult success: %s"), result);
	}

	// last callback - tell the outgoing Command handler we are finally done
	m_outgoingIMHandler->messageFinished();

	return MojErrNone;
}
/*
 * Receive a request for authorization (accept/deny) from another user to add us to their buddy list
 */
bool IMServiceHandler::receivedBuddyInvite(const char* serviceName, const char* username, const char* usernameFrom, const char* customMessage)
{
	// log the parameters
	MojLogInfo (IMServiceApp::s_log, _T("receivedBuddyInvite - serviceName: %s username: %s usernameFrom: %s message: %s"), serviceName, username, usernameFrom, customMessage);

	// Create an imcommand for the application to prompt user for acceptance
	MojRefCountedPtr<BuddyStatusHandler> buddyStatusHandler(new BuddyStatusHandler(m_service));
	MojErr err = buddyStatusHandler->receivedBuddyInvite(serviceName, username, usernameFrom, customMessage);

	if (err) {
		MojString error;
		MojErrToString(err, error);
		MojLogError(IMServiceApp::s_log, _T("receivedBuddyInvite failed: %d - %s"), err, error.data());
		return false;
	}

	return true;
}
/*
 * Callback for DB save results
 * Status changes
 */
MojErr SendOneMessageHandler::imSaveMessageResult(MojObject& result, MojErr saveErr)
{
	MojLogTrace(IMServiceApp::s_log);

	if (saveErr) {
		MojString error;
		MojErrToString(saveErr, error);
		MojLogError(IMServiceApp::s_log, _T("save sent im failed. error %d - %s"), saveErr, error.data());
	}
	else {
		MojString json;
		result.toJson(json);
		MojLogInfo(IMServiceApp::s_log, _T("save sent message %s. response: %s"), this->m_currentMsgdbId.data(), json.data());
	}

	// tell the outgoing message handler we are done
	m_outgoingIMHandler->messageFinished();
	
	return MojErrNone;
}
/*
 * Callback for DB delete results
 * deleted buddyStatus record
 */
MojErr SendOneCommandHandler::removeContactResult(MojObject& result, MojErr delErr)
{
	MojLogTrace(IMServiceApp::s_log);

	if (delErr) {
		MojString error;
		MojErrToString(delErr, error);
		MojLogError(IMServiceApp::s_log, _T("removeContactResult failed. error %d - %s"), delErr, error.data());
	}
	else {
		MojString json;
		result.toJson(json);
		MojLogInfo(IMServiceApp::s_log, _T("removeContactResult response: %s"), json.data());
	}

	// last callback - tell the outgoing Command handler we are finally done
	m_outgoingIMHandler->messageFinished();

	return MojErrNone;
}
/*
 * Enabling an IM account requires the following
 *     add com.palm.imloginstate.libpurple record
 */
MojErr OnEnabledHandler::accountEnabled()
{
	MojLogTrace(IMServiceApp::s_log);
	MojLogInfo(IMServiceApp::s_log, _T("accountEnabled id=%s, serviceName=%s"), m_accountId.data(), m_serviceName.data());

	// first see if an imloginstate record already exists for this account. This can happen on an OTA update or restore
	// construct our where clause - find by username and servicename
	MojDbQuery query;
	query.where("serviceName", MojDbQuery::OpEq, m_serviceName);
	query.where("username", MojDbQuery::OpEq, m_username);
	query.from(IM_LOGINSTATE_KIND);

	MojErr err = m_dbClient.find(this->m_findImLoginStateSlot, query);
	if (err) {
		MojString error;
		MojErrToString(err, error);
		MojLogError(IMServiceApp::s_log, _T("accountEnabled: dbClient.find() failed: error %d - %s"), err, error.data());
		// query failed - not much we can do here...
	}

	return err;
}
/*
 * Enabling an IM account requires the following
 *     add com.palm.imloginstate.libpurple record
 */
MojErr OnEnabledHandler::accountEnabled(const MojString& accountId, const MojString& serviceName, const MojString& username)
{
	//TODO: first issue a merge in case the account already exists?
	MojLogTrace(IMServiceApp::s_log);
	MojLogInfo(IMServiceApp::s_log, _T("accountEnabled id=%s, serviceName=%s"), accountId.data(), serviceName.data());

	MojObject imLoginState;
	imLoginState.putString(_T("_kind"), IM_LOGINSTATE_KIND);
	imLoginState.put(_T("accountId"), accountId);
	imLoginState.put(_T("serviceName"), serviceName);
	imLoginState.put(_T("username"), username);
	imLoginState.putString(_T("state"), LOGIN_STATE_OFFLINE);
	imLoginState.putInt(_T("availability"), PalmAvailability::ONLINE); //default to online so we automatically login at first
	MojErr err = m_dbClient.put(m_addImLoginStateSlot, imLoginState);
	if (err != MojErrNone) {
		MojString error;
		MojErrToString(err, error);
		MojLogError(IMServiceApp::s_log, _T("OnEnabledHandler db.put() failed: error %d - %s"), err, error.data());
	}

	return err;
}
Example #22
0
MojErr MojDbLunaServiceDb::recoverDb(MojDbEnv* env, const MojChar* dir, const MojObject& conf)
{
    MojErr err;

    if (m_recoveryScriptPath.empty()) {
        LOG_ERROR(MSGID_LUNA_SERVICE_DB_OPEN,0, "No recovery script, close database");
        return MojErrDbFatal;
    }

    int recoveryResult = system(m_recoveryScriptPath.data());
    if (recoveryResult != 0) {
        LOG_ERROR(MSGID_LUNA_SERVICE_DB_OPEN,
                  3,
                  PMLOGKS("recoveryScript", m_recoveryScriptPath.data()),
                  PMLOGKFV("scriptExecResult", "%i", recoveryResult),
                  PMLOGKS("dbdir", dir),
                  "Can't recovery database with help of recovery script");

        return MojErrDbFatal;   // close database and stop process
    }

    LOG_INFO(MSGID_LUNA_SERVICE_DB_OPEN, 0, "Recovery database success, reopen database" );
    err = openDb(env, dir, conf);

    if (err != MojErrNone) {
        MojString msg;
        MojErrToString(err, msg);
        LOG_ERROR(MSGID_LUNA_SERVICE_DB_OPEN, 3,
                  PMLOGKS("dbdir", dir),
                  PMLOGKS("dbdata", msg.data()),
                  PMLOGKFV("dberror", "%d", err),
                  "Error re-opening database after recovery");

        return err;
    }

    return MojErrNone;
}
/*
 * Change in buddy status
 */
bool IMServiceHandler::updateBuddyStatus(const char* accountId, const char* serviceName, const char* username, int availability,
		const char* customMessage, const char* groupName, const char* buddyAvatarLoc)
{

	MojLogTrace(IMServiceApp::s_log);

	// log the parameters
	MojLogInfo (IMServiceApp::s_log, _T("updateBuddyStatus - accountId: %s, serviceName: %s, username: %s, availability: %i, customMessage: %s, groupName: %s, buddyAvatarLoc: %s"),
			accountId, serviceName, username, availability, customMessage, groupName, buddyAvatarLoc);

	// handle the message
	MojRefCountedPtr<BuddyStatusHandler> buddyStatusHandler(new BuddyStatusHandler(m_service));
	MojErr err = buddyStatusHandler->updateBuddyStatus(accountId, serviceName, username, availability, customMessage, groupName, buddyAvatarLoc);

	if (err) {
		MojString error;
		MojErrToString(err, error);
		MojLogError(IMServiceApp::s_log, _T("updateBuddyStatus failed: %d - %s"), err, error.data());
		return false;
	}

	return true;
}
Example #24
0
MojErr MojDbKindEngine::loadKinds(MojDbReq& req)
{
	MojAssert(isOpen());
	MojAssertWriteLocked(m_db->m_schemaLock);
	MojLogTrace(s_log);

	MojDbQuery query;
	MojErr err = query.from(KindKindId);
	MojErrCheck(err);
	MojDbCursor cursor;
	err = m_db->find(query, cursor, req);
	MojErrCheck(err);

	for (;;) {
		MojObject obj;
		bool found = false;
		err = cursor.get(obj, found);
		MojErrCheck(err);
		if (!found)
			break;
		// load kind
		MojErr loadErr = err = putKind(obj, req);
		MojErrCatchAll(err) {
			MojString id;
			bool found = false;
			MojErr err = obj.get(MojDbServiceDefs::IdKey, id, found);
			MojErrCheck(err);
			MojString errStr;
			MojErrToString(loadErr, errStr);
			MojLogError(s_log, _T("error loading kind '%s' - %s"), id.data(), errStr.data());
		}
	}
	err = cursor.close();
	MojErrCheck(err);

	return MojErrNone;
}
Example #25
0
MojErr MojService::dispatchRequest(MojServiceMessage* msg)
{
	MojAssert(msg);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);

	// get payload
	MojObject payload;
	MojErr reqErr;
	MojErr err = reqErr = msg->payload(payload);
	MojErrCatchAll(err) {
		return msg->replyError(reqErr);
	}
	// get callback
	Category* category = msg->serviceCategory();
	MojAssert(category);
	MojAssert(category && category->m_service == this);
	// invoke
	err = reqErr = category->m_handler->invoke(msg->method(), msg, payload);
	MojErrCatchAll(err) {
		MojString payloadStr;
		(void) payload.toJson(payloadStr);
		MojString errStr;
		(void) MojErrToString(reqErr, errStr);
		MojLogError(s_log, _T("%s (%d) - sender='%s' method='%s' payload='%s'"),
				errStr.data(), (int) reqErr, msg->senderName(), msg->method(), payloadStr.data());

		if (msg->numReplies() == 0) {
			return msg->replyError(reqErr);
		}
	}
	if (msg->numReplies() == 0 && msg->hasData()) {
		return msg->reply();
	}
	return MojErrNone;
}
Example #26
0
MojErr MojDbLunaServiceDb::open(MojGmainReactor& reactor, MojDbEnv* env,
                                const MojChar* serviceName, const MojChar* dir, const MojObject& conf)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);

    // open service
    MojErr err = m_service.open(serviceName);
    MojErrCheck(err);
    err = m_service.attach(reactor.impl());
    MojErrCheck(err);
    // open handler
    err = m_handler->open();
    MojErrCheck(err);
    err = m_service.addCategory(MojDbServiceDefs::Category, m_handler.get());
    MojErrCheck(err);

    LOG_DEBUG("[MojDb] service name: %s", serviceName);

    // open db
    err = openDb(env, dir, conf);
    if (err != MojErrNone) {
        MojString msg;
        MojErrToString(err, msg);
        LOG_WARNING(MSGID_LUNA_SERVICE_DB_OPEN,
                      3,
                      PMLOGKS("dbdir", dir),
                      PMLOGKS("dbdata", msg.data()),
                      PMLOGKFV("dberror", "%d", err),
                      "Can't open database");

        err = recoverDb(env, dir, conf);
        MojErrCheck(err);
    }

    return err;
}
/*
 * Add buddy record to the buddyStatus and contact DB
 */
MojErr SendOneCommandHandler::addBuddyToDb() {

	// first we have to figure out the accountId - query ImLoginState

	//construct our where clause - find by username and servicename
	MojDbQuery query;
	query.where("serviceName", MojDbQuery::OpEq, m_serviceName);
	query.where("username", MojDbQuery::OpEq, m_username);
	query.from(IM_LOGINSTATE_KIND);

	// call del
	// virtual MojErr del(Signal::SlotRef handler, const MojDbQuery& query,
	//					   MojUInt32 flags = MojDb::FlagNone);
	MojErr err = m_dbClient.find(this->m_findAccountIdForAddSlot, query);
	if (err) {
		MojString error;
		MojErrToString(err, error);
		MojLogError(IMServiceApp::s_log, _T("addBuddy: dbClient.find() failed: error %d - %s"), err, error.data());
		// query failed - not much we can do here...
		m_outgoingIMHandler->messageFinished();
	}

	return MojErrNone;
}
/*
 * Send one IMMessage that was in the outbox. See java code in TransportCallbackThread.sendImHelper()
 * Change the message status from pending to either successful or failed in the DB when done
 * Set timestamp on the message and save it.
 *
 * errors returned up to OutgoingIMHandler
 *
 *  send payload format:
 *  im.libpurple.palm	//sendMessage	string=“{"serviceName":"gmail","usernameTo":"*****@*****.**","messageText":"Test send from phone","username":"******"}”
 *  luna://im.libpurple.palm/sendMessage '{"serviceName":"aol","usernameTo":"palm","messageText":"test send IM","username":"******"}'
 *
 * @param imMsg - imMessage that was read out of the DB with status pending and folder set to outbox
 */
MojErr SendOneMessageHandler::doSend(const MojObject imMsg) {

	MojErr err = MojErrNone;

	// body
	// text should be saved unescaped in the DB
	bool found = false;
	err = imMsg.get(MOJDB_MSG_TEXT, m_messageText, found);
	MojErrCheck(err);

	// userNameTo - use "to" address
	MojObject addrArray; // array
	found = imMsg.get(MOJDB_TO, addrArray);

	// now read the address out of the object
	MojObject toAddrObject;
	if (found) {
		found = addrArray.at(0, toAddrObject);
		err = toAddrObject.get(MOJDB_ADDRESS, m_usernameTo, found);
		MojErrCheck(err);
	}

	// user = "******" address
	MojObject fromAddrObject;
	found = imMsg.get(MOJDB_FROM, fromAddrObject);
	if (found) {
		err = fromAddrObject.get(MOJDB_ADDRESS, m_username, found);
		MojErrCheck(err);
	}

	// serviceName
	err = imMsg.get(MOJDB_SERVICENAME, m_serviceName, found);
	MojErrCheck(err);

	// get the id so we can update the status in  the DB after sending
	err = imMsg.getRequired("_id", m_currentMsgdbId);
	MojErrCheck(err);

	// need to search buddy list to see if this user is on it.
	// first we have to figure out the accountId - query ImLoginState

	// construct our where clause - find by username and servicename
	MojDbQuery query;
	query.where("serviceName", MojDbQuery::OpEq, m_serviceName);
	query.where("username", MojDbQuery::OpEq, m_username);
	query.from(IM_LOGINSTATE_KIND);

	// call del
	// virtual MojErr del(Signal::SlotRef handler, const MojDbQuery& query,
	//					   MojUInt32 flags = MojDb::FlagNone);
	err = m_dbClient.find(this->m_findAccountIdSlot, query);
	if (err) {
		MojString error;
		MojErrToString(err, error);
		MojLogError(IMServiceApp::s_log, _T("doSend: dbClient.find() failed: error %d - %s"), err, error.data());
		// tell the outgoing Command handler we are done
		failMessage(ERROR_SEND_GENERIC_ERROR);
	}

	return MojErrNone;
}
/*
 * Result callback for the listAccountsTemplate
 *
 * result list form:
 * {
		"templateId": "com.palm.aol",
		"loc_name": "AOL",
		"validator": "palm://com.palm.imaccountvalidator/checkCredentials",
		"capabilityProviders": [
			{
				"capability": "MESSAGING",
				"capabilitySubtype": "IM",
				"id": "com.palm.aol.aim",
				"loc_name": "AIM",
				"loc_shortName": "AIM",
				"icon": {
					"loc_32x32": "/usr/palm/public/accounts/com.palm.aol/images/aim32x32.png",
					"loc_48x48": "/usr/palm/public/accounts/com.palm.aol/images/aim48x48.png",
					"splitter": "/usr/palm/public/accounts/com.palm.aol/images/aim_transport_splitter.png"
				},
				"implementation": "palm://com.palm.imlibpurple/",
				"onEnabled": "palm://com.palm.imlibpurple/onEnabled",
				"serviceName": "type_aim",
				"dbkinds": {
					"immessage": "com.palm.immessage.libpurple",
					"imcommand": "com.palm.imcommand.libpurple"
				}
			}
		]
	},
 */
MojErr SendOneMessageHandler::listAccountResult(MojObject& result, MojErr err)
{
	if (err) {
		MojString error;
		MojErrToString(err, error);
		MojLogError(IMServiceApp::s_log, _T("listAccountTemplates failed. error %d - %s"), err, error.data());
		// not much we can do here...don't leave message pending
		failMessage(ERROR_SEND_GENERIC_ERROR);

	}
	else {
		IMServiceHandler::logMojObjectJsonString(_T("listAccountTemplates success: %s"), result);

		// if the flag is not there, assume we can send to a non buddy
		// if we got here, the message is going to a non buddy
		bool nonBuddyChatOK = true;

		// find the template and provider for our service and look for "chatWithNonBuddies":false
		// "results" in result
		MojObject results;
		result.get(_T("results"), results);

		// check to see if array is empty - should not be...
		if (!results.empty()){

			// find the messaging capability object
			MojObject capability;
			MojObject accountTemplate;
			MojString serviceName;
			bool found = false;
			bool foundService = false;

			MojObject::ConstArrayIterator templItr = results.arrayBegin();
			while (templItr != results.arrayEnd()) {
				accountTemplate = *templItr;
				IMServiceHandler::logMojObjectJsonString(_T("listAccountTemplates template: %s"), accountTemplate);

				// now find the capabilityProviders array
				MojObject providersArray;
				found = accountTemplate.get(XPORT_CAPABILITY_PROVIDERS, providersArray);
				if (found) {
					MojObject::ConstArrayIterator capItr = providersArray.arrayBegin();
					while (capItr != providersArray.arrayEnd()) {
						capability = *capItr;
						IMServiceHandler::logMojObjectJsonString(_T("listAccountTemplates capability: %s"), capability);

						// find the one for our service
						capability.get(XPORT_SERVICE_TYPE, serviceName, found);
						if (found) {
							MojLogInfo(IMServiceApp::s_log, _T("listAccountTemplates - capability service %s. "), serviceName.data());
							if (0 == serviceName.compare(m_serviceName)) {
								foundService = true;
								found = capability.get("chatWithNonBuddies", nonBuddyChatOK);
								MojLogInfo(IMServiceApp::s_log, _T("listAccountTemplates - found service %s. found %d, chatWithNonBuddies %d"), m_serviceName.data(), found, nonBuddyChatOK);
								break;
							}
						}
						else MojLogError(IMServiceApp::s_log, _T("error: no service name in capability provider"));
						capItr++;
					}
				}
				else MojLogError(IMServiceApp::s_log, _T("error: no provider array in templateId"));
				if (foundService)
					break;
				templItr++;
			}
		}
		if (nonBuddyChatOK){
			// send to the transport
			sendToTransport();
		}
		else {
			// permanent error - no retry option
			MojLogError(IMServiceApp::s_log, _T("error: Trying to send to user that is not on buddy list"));
			failMessage(ERROR_SEND_TO_NON_BUDDY);
		}
	}

	return MojErrNone;
}
MojErr OnEnabledHandler::findImLoginStateResult(MojObject& payload, MojErr err)
{
	MojLogTrace(IMServiceApp::s_log);

	if (err != MojErrNone) {
		MojString error;
		MojErrToString(err, error);
		MojLogCritical(IMServiceApp::s_log, _T("findImLoginStateResult failed: error %d - %s"), err, error.data());
	}
	else {
		// "results" in result
		MojObject results;
		payload.get(_T("results"), results);

		// check to see if array is empty - normally it will be if this is a newly created account. There should never be more than 1 item here
		if (!results.empty()){

			IMServiceHandler::logMojObjectJsonString(_T("findImLoginStateResult found existing imLoginState record: %s"), payload);

			// if there is a record already, make sure the account id matches.
			MojObject loginState;
			MojObject::ConstArrayIterator itr = results.arrayBegin();
			bool foundOne = false;
			while (itr != results.arrayEnd()) {
				if (foundOne) {
					MojLogError(IMServiceApp::s_log,
							_T("findImLoginStateResult: found more than one ImLoginState with same username/serviceName - using the first one"));
					break;
				}
				loginState = *itr;
				foundOne = true;
				itr++;
			}

			MojString accountId;
			MojErr err = loginState.getRequired("accountId", accountId);
			if (err) {
				MojLogError(IMServiceApp::s_log, _T("findImLoginStateResult: missing accountId in loginState entry"));
			}
			if (0 != accountId.compare(m_accountId)) {
				MojLogError(IMServiceApp::s_log, _T("findImLoginStateResult: existing loginState record does not have matching account id. accountId = %s"), accountId.data());

				// delete this record
				MojObject idsToDelete;
				MojString dbId;
				err = loginState.getRequired("_id", dbId);
				if (err) {
					MojLogError(IMServiceApp::s_log, _T("findImLoginStateResult: missing dbId in loginState entry"));
				}
				else {
				    idsToDelete.push(dbId);

					// luna://com.palm.db/del '{"ids":[2]}'
					MojLogInfo(IMServiceApp::s_log, _T("findImLoginStateResult: deleting loginState entry id: %s"), dbId.data());
					err = m_dbClient.del(this->m_deleteImLoginStateSlot, idsToDelete.arrayBegin(), idsToDelete.arrayEnd());
					if (err != MojErrNone) {
						MojString error;
						MojErrToString(err, error);
						MojLogError(IMServiceApp::s_log, _T("findImLoginStateResult: db.del() failed: error %d - %s"), err, error.data());
					}
				}
			}
			// if the account id matches, leave the old record and we are done
			else return MojErrNone;
		}

		// no existing record found or the old one was deleted - create a new one
		MojLogInfo(IMServiceApp::s_log, _T("findImLoginStateResult: no matching loginState record found for %s, %s. creating a new one"), m_username.data(), m_serviceName.data());
		MojObject imLoginState;
		imLoginState.putString(_T("_kind"), IM_LOGINSTATE_KIND);
		imLoginState.put(_T("accountId"), m_accountId);
		imLoginState.put(_T("serviceName"), m_serviceName);
		imLoginState.put(_T("username"), m_username);
        imLoginState.put(_T("capabilityId"), m_capabilityProviderId);
		imLoginState.putString(_T("state"), LOGIN_STATE_OFFLINE);
		imLoginState.putInt(_T("availability"), PalmAvailability::ONLINE); //default to online so we automatically login at first
        imLoginState.put(_T("config"), m_config);
		MojErr err = m_dbClient.put(m_addImLoginStateSlot, imLoginState);
		if (err != MojErrNone) {
			MojString error;
			MojErrToString(err, error);
			MojLogError(IMServiceApp::s_log, _T("findImLoginStateResult: db.put() failed: error %d - %s"), err, error.data());
		}

	}
	return err;
}