$device->policykey = 0;
$device->rwstatus = self::RWSTATUS_NA;
$device->user = $this->_driver->getUser();
- $state->setDeviceInfo($devId, $device);
+ $device->id = $devId;
+ $state->setDeviceInfo($device);
}
/* Load the request handler to handle the request */
$this->_encoder,
$this->_request,
$this,
+ $devId,
$this->_provisioning);
$request->setLogger($this->_logger);
- $result = $request->handle($this, $devId);
+ $result = $request->handle();
$this->_driver->logOff();
return $result;
* Add a folder deletion to the cache (used during FolderSync Requests).
*
* @param string $id The folder id
- *
+ *
* @return boolean
*/
public function folderDeletion($id)
* @param string $id
* @param string $displayname
* @param string $type
- *
+ *
* @return boolean
*/
public function changeFolder($parent, $id, $displayname, $type)
protected $_version;
/**
- * The device Id
- *
- * @var string
- */
- protected $_devId;
-
- /**
* Used to track what error code to send back to PIM on failure
*
* @var integer
/**
* ActiveSync server
- *
- * @var Horde_ActiveSync
+ *
+ * @var Horde_ActiveSync
*/
protected $_activeSync;
protected $_logger;
/**
+ * The device info
+ *
+ * @var stdClass
+ */
+ protected $_device;
+
+ /**
* Const'r
*
* @param Horde_ActiveSync_Driver $driver The backend driver
Horde_ActiveSync_Wbxml_Encoder $encoder,
Horde_Controller_Request_Http $request,
Horde_ActiveSync $as,
+ $devId,
$provisioning)
{
/* Backend driver */
/* Provisioning support */
$this->_provisioning = $provisioning;
+
+ /* Get the state object */
+ $this->_state = &$driver->getStateObject();
+
+ /* Device info */
+ $this->_device = $this->_state->getDeviceInfo($devId);
}
/**
* header - which is against the specification. Check the user agent
* for Android (maybe need version sniffing in the future) and set the
* policykey to null for those devices. */
+ $this->_device = $this->_state->getDeviceInfo($this->_devId);
+ if (strpos($this->_device->agent, 'Android') !== false) {
+ $sentKey = null;
+ }
-
/* Don't attempt if we don't care */
if ($this->_provisioning !== false) {
$state = $this->_driver->getStateObject();
* @param string $version
* @param string $devId
*/
- public function handle(Horde_ActiveSync $activeSync, $devId)
+ public function handle()
{
$this->_version = $activeSync->getProtocolVersion();
- $this->_devId = $devId;
- $this->_logger->info('Request received from device: ' . $devId . ' Supporting protocol version: ' . $this->_version);
+ $this->_logger->info('Request received from device: ' . $this->_device->id . ' Supporting protocol version: ' . $this->_version);
}
}
/**
* Handle the request.
*
- * @param Horde_ActiveSync $activeSync The activesync server object
- * @param string $devId The device id
- *
* @return boolean
*/
- public function handle(Horde_ActiveSync $activeSync, $devId)
+ public function handle()
{
- parent::handle($activeSync, $devId);
+ parent::handle();
/* Be optimistic */
$this->_statusCode = self::STATUS_SUCCESS;
$this->_logger->info('[Horde_ActiveSync::handleFolderSync] Beginning FOLDERSYNC');
/* Check policy */
- if (!$this->checkPolicyKey($activeSync->getPolicyKey())) {
+ if (!$this->checkPolicyKey($this->_activeSync->getPolicyKey())) {
return false;
}
$this->_logger->debug('[Horde_ActiveSync::handleFolderSync] syncKey: ' . $synckey);
/* Initialize state engine */
- $this->_state = &$this->_driver->getStateObject(array('synckey' => $synckey));
- $this->_state->getDeviceInfo($devId);
+ $this->_state->init(array('synckey' => $synckey));
try {
/* Get folders that we know about already */
$this->_state->loadState($synckey, 'foldersync');
* @return boolean
* @throws Horde_ActiveSync_Exception
*/
- public function handle(Horde_ActiveSync $activeSync, $devId)
+ public function handle()
{
- parent::handle($activeSync, $devId);
- $this->_logger->info('[Horde_ActiveSync::handleFolderSync] Beginning GETITEMESTIMATE');
+ parent::handle();
+ $this->_logger->info('[' . $this->_device->id . '] Beginning GETITEMESTIMATE');
/* Check policy */
- if (!$this->checkPolicyKey($activeSync->getPolicyKey())) {
+ if (!$this->checkPolicyKey($this->_activeSync->getPolicyKey())) {
return false;
}
$status = array();
$collections = array();
-
if (!$this->_decoder->getElementStartTag(self::GETITEMESTIMATE) ||
!$this->_decoder->getElementStartTag(self::FOLDERS)) {
/* compatibility mode - get id from state */
if (!isset($collectionid)) {
- $this->_state = &$this->_driver->getStateObject();
- $this->_state->getDeviceInfo($devId);
- $collectionid = $this->_state>getFolderData($this->_devid, $collection['class']);
+ $collectionid = $this->_state>getFolderData($this->_device->id, $collection['class']);
}
$collection['id'] = $collectionid;
$status[$collection['id']] = $cStatus;
$this->_encoder->endTag();
$this->_encoder->startTag(self::ESTIMATE);
- $this->_state = $this->_driver->getStateObject($collection);
+ $this->_state->init($collection);
$this->_state->loadState($collection['synckey']);
$sync = $this->_driver->getSyncObject();
$sync->init($this->_state, null, $collection);
*/
class Horde_ActiveSync_Request_Options extends Horde_ActiveSync_Request_Base
{
- public function handle(Horde_ActiveSync $activeSync, $devId)
+ public function handle()
{
Horde_ActiveSync::activeSyncHeader();
Horde_ActiveSync::versionHeader();
*
* @return boolean
*/
- public function handle(Horde_ActiveSync $activeSync, $devId)
+ public function handle()
{
$now = time();
- parent::handle($activeSync, $devId);
+ parent::handle();
/* Get the settings for the server */
$this->_ping_settings = $this->_driver->getHeartbeatConfig();
$timeout = $this->_ping_settings['waitinterval'];
/* Notify */
- $this->_logger->info('[' . $devId . '] PING received at timestamp: ' . $now . '.');
+ $this->_logger->info('[' . $this->_device->id . '] PING received at timestamp: ' . $now . '.');
/* Glass half full kinda guy... */
$this->_statusCode = self::STATUS_NOCHANGES;
/* Initialize the state machine */
$this->_state = &$this->_driver->getStateObject();
- $this->_state->getDeviceInfo($devId);
+ $this->_state->getDeviceInfo($this->_device->id);
/* See if we have an existing PING state. Need to do this here, before
* we read in the PING request since the PING request is allowed to omit
* sections if they have been sent previously */
- $collections = array_values($this->_state->initPingState($this->_devId));
+ $collections = array_values($this->_state->initPingState($this->_device->id));
$lifetime = $this->_checkHeartbeat($this->_state->getHeartbeatInterval());
/* Build the $collections array if we receive request from PIM */
/* Start waiting for changes, but only if we don't have any errors */
if ($this->_statusCode == self::STATUS_NOCHANGES) {
- $this->_logger->info(sprintf('[%s] Waiting for changes (heartbeat interval: %d)', $this->_devId, $lifetime));
+ $this->_logger->info(sprintf('[%s] Waiting for changes (heartbeat interval: %d)', $this->_device->id, $lifetime));
$expire = $now + $lifetime;
while (time() <= $expire) {
/* Check the remote wipe status and request a foldersync if
* we want the device wiped. */
if ($this->_provisioning === true) {
- $rwstatus = $this->_state->getDeviceRWStatus($this->_devId);
+ $rwstatus = $this->_state->getDeviceRWStatus($this->_device->id);
if ($rwstatus == Horde_ActiveSync::RWSTATUS_PENDING || $rwstatus == Horde_ActiveSync::RWSTATUS_WIPED) {
$this->_statusCode = self::STATUS_FOLDERSYNCREQD;
break;
for ($i = 0; $i < count($collections); $i++) {
$collection = $collections[$i];
- $collection['synckey'] = $this->_devId;
+ $collection['synckey'] = $this->_device->id;
$sync = $this->_driver->getSyncObject();
try {
$this->_state->loadPingCollectionState($collection);
}
if ($dataavailable) {
- $this->_logger->info('[' . $this->_devId . '] Changes available');
+ $this->_logger->info('[' . $this->_device->id . '] Changes available');
break;
}
/* Wait a bit before trying again */
}
/* Prepare for response */
- $this->_logger->info('[' . $this->_devId . '] Sending response for PING.');
+ $this->_logger->info('[' . $this->_device->id . '] Sending response for PING.');
$this->_encoder->StartWBXML();
$this->_encoder->startTag(self::PING);
* the client to perform this PROVISION request...so we are handling phase
* 2 (download policies) and 3 (acknowledge policies) here.
*
- * @param Horde_ActiveSync $activeSync The activesync object.
- *
* @return boolean
* @throws Horde_ActiveSync_Exception
*/
- public function handle(Horde_ActiveSync $activeSync, $devId)
+ public function handle()
{
- parent::handle($activeSync, $devId);
+ parent::handle();
/* Get the policy key if it was sent */
- $policykey = $activeSync->getPolicyKey();
+ $policykey = $this->_activeSync->getPolicyKey();
+ $this->_logger->debug('[' . $this->_device->id . '] PIM PolicyKey: ' . $policykey);
- $this->_logger->debug('PIM PolicyKey: ' . $policykey);
/* Be optimistic */
$status = self::STATUS_SUCCESS;
$policyStatus = self::STATUS_SUCCESS;
return $this->_globalError(self::STATUS_PROTERROR);
}
- /* Get state object */
- $this->_state = $this->_driver->getStateObject();
- $this->_state->getDeviceInfo($devId);
-
/* Handle android remote wipe */
if ($this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_REMOTEWIPE)) {
if (!$this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_STATUS)) {
/* POLICYKEY is only sent by client in phase 3 */
if ($this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_POLICYKEY)) {
$policykey = $this->_decoder->getElementContent();
- $this->_logger->debug('PHASE 3 policykey sent from PIM: ' . $policykey);
+ $this->_logger->debug('[' . $this->_device->id .'] PHASE 3 policykey sent from PIM: ' . $policykey);
if (!$this->_decoder->getElementEndTag() ||
!$this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_STATUS)) {
* @param $protocolversion
* @return unknown_type
*/
- public function handle(Horde_ActiveSync $activeSync, $devId)
+ public function handle()
{
- $this->_logger->info('[' . $devId . '] Handling SendMail command.');
-
+ $this->_logger->info('[' . $this->_device->id . '] Handling SendMail command.');
+
// All that happens here is that we receive an rfc822 message on stdin
// and just forward it to the backend. We provide no output except for
// an OK http reply
* Consult LICENSE file for details
*/
class Horde_ActiveSync_Request_Sync extends Horde_ActiveSync_Request_Base
-{
+{
/* Status */
const STATUS_SUCCESS = 1;
const STATUS_VERSIONMISM = 2;
* @return boolean
* @throws Horde_ActiveSync_Exception
*/
- public function handle(Horde_ActiveSync $activeSync, $devId)
+ public function handle()
{
- parent::handle($activeSync, $devId);
- $this->_logger->info('[' . $this->_devId . '] Handling SYNC command.');
+ parent::handle();
+ $this->_logger->info('[' . $this->_device->id . '] Handling SYNC command.');
/* Check policy */
- if (!$this->checkPolicyKey($activeSync->getPolicyKey())) {
+ if (!$this->checkPolicyKey($this->_activeSync->getPolicyKey())) {
return false;
}
}
$collection['class'] = $this->_decoder->getElementContent();
- $this->_logger->info('[' . $this->_devId . '] Syncing folder class: ' . $collection['class']);
+ $this->_logger->info('[' . $this->_device->id . '] Syncing folder class: ' . $collection['class']);
if (!$this->_decoder->getElementEndTag()) {
throw new Horde_ActiveSync_Exception('Protocol error');
}
if ($this->_decoder->getElementStartTag(Horde_ActiveSync::SYNC_FOLDERID)) {
$collection['id'] = $this->_decoder->getElementContent();
- $this->_logger->info('[' . $this->_devId . '] Folder server id: ' . $collection['id']);
+ $this->_logger->info('[' . $this->_device->id . '] Folder server id: ' . $collection['id']);
if (!$this->_decoder->getElementEndTag()) {
throw new Horde_ActiveSync_Exception('Protocol error');
}
if ($this->_statusCode == self::STATUS_SUCCESS) {
/* Initialize the state */
- $this->_state = &$this->_driver->getStateObject($collection);
- $device = $this->_state->getDeviceInfo($devId);
+ $this->_state->init($collection);
if (!empty($collection['supported'])) {
/* Initial sync and we have SUPPORTED data - save it */
- if (empty($device->supported)) {
- $device->supported = array();
+ if (empty($this->_device->supported)) {
+ $this->_device->supported = array();
}
- $device->supported[$collection['class']] = $collection['supported'];
- $this->_state->setDeviceInfo($devId, $device);
+ $this->_device->supported[$collection['class']] = $collection['supported'];
+ $this->_state->setDeviceInfo($this->_device);
}
try {
$this->_state->loadState($collection['synckey'], 'sync');
/* compatibility mode - get folderid from the state directory */
if (!isset($collection['id'])) {
- $collection['id'] = $this->_state->getFolderData($this->_devId, $collection['class']);
+ $collection['id'] = $this->_state->getFolderData($this->_device->id, $collection['class']);
}
/* compatibility mode - set default conflict behavior if no
if (isset($appdata->read)) {
$importer->importMessageReadFlag($serverid, $appdata->read);
} else {
- $importer->importMessageChange($serverid, $appdata, $device);
+ $importer->importMessageChange($serverid, $appdata, $this->_device);
}
$collection['importedchanges'] = true;
}
break;
case Horde_ActiveSync::SYNC_ADD:
if (isset($appdata)) {
- $id = $importer->importMessageChange(false, $appdata, $device);
+ $id = $importer->importMessageChange(false, $appdata, $this->_device);
if ($clientid && $id) {
$collection['clientids'][$clientid] = $id;
$collection['importedchanges'] = true;
}
}
- $this->_logger->debug(sprintf('[%s] Processed %d incoming changes', $this->_devId, $nchanges));
+ $this->_logger->debug(sprintf('[%s] Processed %d incoming changes', $this->_device->id, $nchanges));
if (!$this->_decoder->getElementEndTag()) {
// end commands
}
/* Start output to PIM */
- $this->_logger->info('[' . $this->_devId . '] Beginning SYNC Response.');
+ $this->_logger->info('[' . $this->_device->id . '] Beginning SYNC Response.');
$this->_encoder->startWBXML();
$this->_encoder->startTag(Horde_ActiveSync::SYNC_SYNCHRONIZE);
$this->_encoder->startTag(Horde_ActiveSync::SYNC_FOLDERS);
$n++;
if (!empty($collection['windowsize']) && $n >= $collection['windowsize']) {
- $this->_logger->info(sprintf('[%s] Exported maxItems of messages: %d - more available.', $this->_devId, $collection['windowsize']));
+ $this->_logger->info(sprintf('[%s] Exported maxItems of messages: %d - more available.', $this->_device->id, $collection['windowsize']));
break;
}
}
$this->_state->setNewSyncKey($collection['newsynckey']);
$this->_state->save();
} else {
- $this->_logger->err(sprintf('[%s] Error saving %s - no state information available.', $this->_devId, $collection['newsynckey']));
+ $this->_logger->err(sprintf('[%s] Error saving %s - no state information available.', $this->_device->id, $collection['newsynckey']));
}
}
}
$collection['newsynckey'] = Horde_ActiveSync_State_Base::getNewSyncKey(($this->_statusCode == self::STATUS_KEYMISM) ? 0 : $collection['synckey']);
if ($collection['synckey'] != 0) {
- $this->_state = &$this->_driver->getStateObject($collection);
+ $this->_state->init($collection);
$this->_state->removeState($collection['synckey']);
}
}
*
* @return boolean
*/
- abstract public function setDeviceInfo($devId, $data);
+ abstract public function setDeviceInfo($data);
/**
* Explicitly remove a state from storage.
$device->rwstatus = Horde_ActiveSync::RWSTATUS_NA;
$device->deviceType = '';
$device->userAgent = '';
+ $device->id = $devId;
return $device;
}
*
* @return boolean
*/
- public function setDeviceInfo($devId, $data)
+ public function setDeviceInfo($data)
{
$this->_ensureUserDirectory();
- $this->_devId = $devId;
- $file = $this->_stateDir . '/' . $this->_backend->getUser() . '/info-' . $devId;
+ $this->_devId = $data->id;
+ $file = $this->_stateDir . '/' . $this->_backend->getUser() . '/info-' . $this->_devId;
return file_put_contents($file, serialize($data));
}
{
$info = $this->getDeviceInfo($devId);
$info->policykey = $key;
- $this->setDeviceInfo($devId, $info);
+ $this->setDeviceInfo($info);
$this->_logger->info('[' . $devId . '] New policykey saved: ' . $key);
}
{
$info = $this->getDeviceInfo($devId);
$info->rwstatus = $status;
- $this->setDeviceInfo($devId, $info);
+ $this->setDeviceInfo($info);
$this->_logger->info('[' . $devId . '] Setting DeviceRWStatus: ' . $status);
}
if (!array_key_exists(Horde_ActiveSync::FOLDER_TYPE_CONTACT, $unique_folders)) {
$unique_folders[Horde_ActiveSync::FOLDER_TYPE_CONTACT] = Horde_ActiveSync::FOLDER_TYPE_DUMMY;
}
-
+
/* Storage to SQL? */
$sql = 'UPDATE ' . $this->_syncDeviceTable . ' SET device_folders = ? WHERE device_id = ?';
try {
$this->_deviceInfo->userAgent = '';
$this->_deviceInfo->id = $devId;
$this->_deviceInfo->user = $this->_backend->getUser();
- $this->setDeviceInfo($devId, $this->_deviceInfo);
+ $this->setDeviceInfo($this->_deviceInfo);
$this->resetPingState();
}
/**
* Set new device info
*
- * @param string $devId The device id.
* @param StdClass $data The device information
*
* @return boolean
*/
- public function setDeviceInfo($devId, $data)
+ public function setDeviceInfo($data)
{
/* Delete the old entry, just in case */
$this->_deviceInfo = $data;
try {
$query = 'DELETE FROM ' . $this->_syncDeviceTable . ' WHERE device_id = ?';
- $this->_db->execute($query, array($devId));
+ $this->_db->execute($query, array($data->id));
$query = 'INSERT INTO ' . $this->_syncDeviceTable
. '(device_type, device_agent, device_ping, device_policykey, device_rwstatus, device_id, device_user, device_supported)'
'',
$data->policykey,
$data->rwstatus,
- $devId,
+ $data->id,
$data->user,
(!empty($data->supported) ? serialize($data->supported) : ''));
- $this->_devId = $devId;
+ $this->_devId = $data->id;
return $this->_db->insert($query, $values);
} catch (Horde_Db_Exception $e) {