📄 obexcomminitiator.cpp
字号:
/* -*- c++ -*- --------------------------------------------------------------- Copyright (C) 2005, SWECO, All Rights Reserved. Implementation of OBEXCommInitiator class Author: Zsolt Molnar (Zsolt.Molnar@ieee.org) ---------------------------------------------------------------------------*/#include <iostream>#include <fstream>#include "base.hh"#include "AppFactory.hh"#include "OBEXCommInitiator.hh"namespace { const char rcs_id[] = "$Id$"; }map<Device::tDeviceType, OBEXInitSequence> OBEXCommInitiator::_initStore;OBEXCommInitiator::OBEXCommInitiator() : _fileName(CFG_DEV_DB_FNAME){ if (_initStore.empty()) { _fillInitStore(); } if (_deviceDb.empty()) { _load(); }}bool OBEXCommInitiator::perform(const Device& aDevice){ bool ret = false; IOBEXSender::tSendState sendRes; lock(); // Look if the device type is supported _tInitStore::iterator seqPos = _initStore.find(aDevice.devType); if (seqPos == _initStore.end()) { cout << "OBEXCommInitiator: device type of " << aDevice.devID << " is not supported" << endl; _deviceDb[aDevice] = NOT_SUPPORTED; goto OUT; } // Handle the case when the device is not already recognized. if (_checkIfProcess(aDevice)) { unlock(); sendRes = _initCommunication(aDevice, seqPos->second); lock(); _setInitState(aDevice, sendRes); _save(); } ret = (_deviceDb[aDevice] == ACCEPTED);OUT: unlock(); return ret;}void OBEXCommInitiator::reset(const set<Device>& aDevices){ lock(); for (set<Device>::iterator resetItr = aDevices.begin(); resetItr != aDevices.end(); ++resetItr) { _tDeviceDb::iterator devPos = _deviceDb.find(*resetItr); if (devPos != _deviceDb.end()) { _deviceDb.erase(devPos); } } unlock();}boolOBEXCommInitiator::_checkIfProcess(const Device& aDevice){ _tDeviceDb::iterator devPos = _deviceDb.find(aDevice); if (devPos == _deviceDb.end()) { _deviceDb[aDevice] = PROCESSING; return true; } else if (devPos->second == RETRY) { devPos->second = PROCESSING; return true; } return false;}IOBEXSender::tSendStateOBEXCommInitiator::_initCommunication(const Device& aDevice, const OBEXInitSequence& aSeq){ IOBEXSender::tSendState sendRes = IOBEXSender::ACCEPTED; auto_ptr<IOBEXSender> sender(AppFactory::newOBEXSenderC()); sender->setPort(aDevice.devID); // "play" the sequence for (OBEXInitSequence::const_iterator itr = aSeq.begin(); itr != aSeq.end() && sendRes == IOBEXSender::ACCEPTED; ++itr) { sendRes = IOBEXSender::TIMEOUT; unsigned int attempts = 0; // attempt to send the message until accepted or timeout while (attempts <= itr->retryNumber && sendRes == IOBEXSender::TIMEOUT) { sendRes = sender->send(itr->fileName, itr->messageTitle); if (sendRes == IOBEXSender::TIMEOUT) { ++attempts; sleep(itr->attemptDelay); } } // wait a bit before sending the next part of the message if (aSeq.end() - itr > 1) { sleep(OCI_INTERMESSAGE_DELAY); } } return sendRes;}boolOBEXCommInitiator::_setInitState(const Device& aDevice, const IOBEXSender::tSendState& aSendRes){ _tInitState& state = _deviceDb[aDevice]; cout << "OBEXCommInitiator: result of initiating sequence for new device " << aDevice.devID << " is: "; switch (aSendRes) { case IOBEXSender::TIMEOUT: case IOBEXSender::ERROR: state = RETRY; cout << "RETRY"; break; case IOBEXSender::ACCEPTED: state = ACCEPTED; cout << "ACCEPTED"; break; default: state = REFUSED; cout << "REFUSED"; break; } cout << endl; return (state == ACCEPTED);}boolOBEXCommInitiator::_save(){ ofstream out(_fileName.c_str()); if (!out) { return false; } for (_tDeviceDb::iterator itr = _deviceDb.begin(); itr != _deviceDb.end(); ++itr) { out << itr->first.devID << endl << (int)itr->first.devType << endl << (int)itr->second << endl; } return true;}boolOBEXCommInitiator::_load(){ ifstream in(_fileName.c_str()); if (!in) { return false; } Device dev; while (!in.eof()) { in >> dev.devID; int tmp; in >> tmp; dev.devType = (Device::tDeviceType)tmp; in >> tmp; _deviceDb[dev] = (_tInitState)tmp; } return true;}void OBEXCommInitiator::_fillInitStore(){ OBEXInitItem seq; string picWelcome("SWECO Welcome"); // For NOKIA6600 seq.fileName = "SWECO_Welcome"; seq.messageTitle = picWelcome; seq.retryNumber = 3; seq.attemptDelay = 5; _initStore[Device::NOKIA6600].push_back(seq); seq.fileName = "sweco.sis"; seq.messageTitle = "SWECO application"; seq.retryNumber = 2; seq.attemptDelay = 5; _initStore[Device::NOKIA6600].push_back(seq); // For NOKIA7610 seq.fileName = "SWECO_Welcome"; seq.messageTitle = picWelcome; seq.retryNumber = 3; seq.attemptDelay = 5; _initStore[Device::NOKIA7610].push_back(seq); seq.fileName = "sweco.sis"; seq.messageTitle = "SWECO application"; seq.retryNumber = 2; seq.attemptDelay = 5; _initStore[Device::NOKIA7610].push_back(seq); // For other devices seq.fileName = "OTHER_Welcome"; seq.messageTitle = picWelcome; seq.retryNumber = 3; seq.attemptDelay = 5; _initStore[Device::OTHER].push_back(seq);}#ifdef __TEST__#include <assert.h>#include <iostream>boolOBEXCommInitiator::test(){ Device dev_1("00:0E:6D:32:0D:FF", Device::NOKIA6600); Device dev_2("00:60:57:A3:DF:28", Device::OTHER); Device dev_3("dev_3", Device::UNKNOWN); cout << "Switch on Nokia 6600 (ID: " << dev_1.devID << " and " << dev_2.devID << ") bluetooth " << "and press enter" << endl << endl; getchar(); cout << "Accept both messages on device " << dev_1.devID << endl << endl; assert(_deviceDb.empty()); assert(perform(dev_1)); assert(_deviceDb.size() == 1); assert(_deviceDb[dev_1] == ACCEPTED); // No new device introduced by the [] operator... assert(_deviceDb.size() == 1); cout << "Refuse the first message on device " << dev_2.devID << endl << endl; assert(!perform(dev_2)); assert(_deviceDb.size() == 2); assert(_deviceDb[dev_2] == REFUSED); // No new device introduced by the [] operator... assert(_deviceDb.size() == 2); // resend to an already accepted device cout << "Now the server should not contact any devices." << endl << endl; assert(perform(dev_1)); assert(!perform(dev_2)); assert(_deviceDb.size() == 2); assert(_deviceDb[dev_2] == REFUSED); assert(_deviceDb[dev_1] == ACCEPTED); assert(_deviceDb.size() == 2); sleep(3); cout << "If the server did not do it, the test item passed." << endl << endl; // Check the unknown device assert(!perform(dev_3)); assert(_deviceDb.size() == 3); assert(_deviceDb[dev_3] == NOT_SUPPORTED); assert(_deviceDb.size() == 3); // OK, now a little cheat. We remove the dev_1 from the database in order // to reuse it... _deviceDb.erase(dev_1); assert(_deviceDb.size() == 2); cout << "Accept the first message, refuse the second one on device " << dev_1.devID << endl << endl; assert(!perform(dev_1)); assert(_deviceDb.size() == 3); assert(_deviceDb[dev_1] == REFUSED); // No new device introduced by the [] operator... assert(_deviceDb.size() == 3); // OK, now a little cheat. We remove the dev_1 from the database in order // to reuse it... _deviceDb.erase(dev_1); assert(_deviceDb.size() == 2); cout << "Wait for 2 timeouts on " << dev_1.devID << endl << endl; int oldRetryNum = _initStore[Device::NOKIA6600][0].retryNumber; _initStore[Device::NOKIA6600][0].retryNumber = 1; assert(!perform(dev_1)); assert(_deviceDb.size() == 3); assert(_deviceDb[dev_1] == RETRY); assert(_deviceDb.size() == 3); _initStore[Device::NOKIA6600][0].retryNumber = oldRetryNum; cout << "OBEXCommInitiator test passed" << endl; return true;}#endif // #ifdef __TEST__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -