bthci/bthci2/hctl/src/hctluartbase.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include "hctluartbase.h"
       
    22 #include "btbusdevcomm.h"
       
    23 
       
    24 #include <bluetooth/logger.h>
       
    25 #include <bluetooth/hci/hciutil.h>
       
    26 
       
    27 #ifdef __FLOG_ACTIVE
       
    28 _LIT8(KLogComponent, LOG_COMPONENT_HCTL_BASE);
       
    29 #endif
       
    30 
       
    31 EXPORT_C CHCTLUartBase::CHCTLUartBase()
       
    32 	{
       
    33 	LOG_FUNC
       
    34 	}
       
    35 
       
    36 EXPORT_C CHCTLUartBase::~CHCTLUartBase()
       
    37 	{
       
    38 	LOG_FUNC
       
    39 	if (iPort)
       
    40 		{
       
    41 		iPort->Close();
       
    42 		delete iPort;
       
    43 		}
       
    44 	}
       
    45 
       
    46 /**
       
    47 	Common method used by UART derivative HCTLs to check hardware is connected
       
    48 */
       
    49 EXPORT_C TBool CHCTLUartBase::CheckHardwareConnected()
       
    50 	{
       
    51 	LOG_FUNC
       
    52 	TBool hwPresent = ETrue;
       
    53 
       
    54 	LOG1(_L8("\tsignals = 0x%02x"), iPort->Signals());
       
    55 
       
    56 	// If there are currently no signals assume the HW is not connected.
       
    57 	if(!iPort->Signals())
       
    58 		{
       
    59 		hwPresent = EFalse;
       
    60 
       
    61 		TRequestStatus lineStatus;
       
    62 		TRequestStatus timeStatus;
       
    63 
       
    64 		TUint testSignals;
       
    65 		RTimer timer;
       
    66 
       
    67 		TInt err = timer.CreateLocal();
       
    68 		if(err == KErrNone)
       
    69 			{
       
    70 			iPort->NotifySignalChange(lineStatus, testSignals);
       
    71 			timer.After(timeStatus, 5000000); // 5s
       
    72 			
       
    73 			User::WaitForRequest(lineStatus, timeStatus); // so we don't wait forever
       
    74 			
       
    75 			if (timeStatus.Int() == KErrNone)
       
    76 				{
       
    77 				// The guard timer has expired.
       
    78 				iPort->NotifySignalChangeCancel();
       
    79 				User::WaitForRequest(lineStatus);	// consume the request
       
    80 				}
       
    81 			else if ( lineStatus.Int() == KErrNone)
       
    82 				{
       
    83 				// The hardware is there.  Cancel the timer.
       
    84 				timer.Cancel();
       
    85 				User::WaitForRequest(timeStatus);	// consume the request
       
    86 				hwPresent = ETrue;
       
    87 				}
       
    88 			}
       
    89 		timer.Close();
       
    90 		}
       
    91 
       
    92 	LOG1(_L8("\thwPresent = %d"), hwPresent);
       
    93 	return hwPresent;
       
    94 	}
       
    95 
       
    96 /**
       
    97 Common method used by UART derivative HCTLs to open the available physical 
       
    98 UART connections for bluetooth hardware
       
    99 */
       
   100 void CHCTLUartBase::OpenPortL(TUint aPortNo)
       
   101 	{
       
   102 	LOG_FUNC
       
   103 	LOG1(_L8("\taPortNo = %d"), aPortNo);
       
   104 	
       
   105 	TInt ret = iPort->Open(aPortNo);
       
   106 	
       
   107 	if(ret != KErrNone && ret != KErrAlreadyExists)
       
   108 		{
       
   109 		LEAVEIFERRORL(ret);
       
   110 		}
       
   111 	}
       
   112 
       
   113 // For debug emulator environments, we provide a mechanism to cycle through possible
       
   114 // port numbers until we find a port to use (it maybe be connected to something other
       
   115 // than Bluetooth hardware, but that has to be identified at a higher level).  This meant
       
   116 // users don't have to fiddle with esk or ini files, especially for the case where they're
       
   117 // running back to back on one PC. 
       
   118 // However, this slows down emulator start-up, so it is configured by ini file which does
       
   119 // mean potentially fiddling with ini files anyway ... c'est la vie.
       
   120 #if(defined(__WINS__) && defined(_DEBUG))
       
   121 #define SYMBIAN_INTERNAL_RETRY_BLUETOOTH_PORT_OPEN
       
   122 #pragma message("If configured, Bluetooth HCTL will scan UARTs to find a connected port")
       
   123 #endif
       
   124 
       
   125 #ifndef SYMBIAN_INTERNAL_RETRY_BLUETOOTH_PORT_OPEN
       
   126 
       
   127 void CHCTLUartBase::ScanAndOpenPortL(TUint /*aStartingPortNo*/)
       
   128 	{
       
   129 	LOG_FUNC
       
   130 	LEAVEL(KErrNotSupported);
       
   131 	}
       
   132 
       
   133 #else
       
   134 
       
   135 /**
       
   136 	Common method used by UART derivative HCTLs to scan the available physical UART connections
       
   137 	for bluetooth hardware
       
   138 */
       
   139 void CHCTLUartBase::ScanAndOpenPortL(TUint aStartingPortNo)
       
   140 	{
       
   141 	LOG_FUNC
       
   142 	LOG1(_L8("\aStartingPortNo = %d"), aStartingPortNo);
       
   143 	TUint portNo = aStartingPortNo;
       
   144 	
       
   145 	TInt ret = KErrNone;
       
   146 	
       
   147 	// This is a limit set by windows.  RBusDevComm will panic if aPortNo of 32 or higher
       
   148 	// is used.  
       
   149 	const TInt KMaxPortNumber = 32;
       
   150 	
       
   151 	while(portNo < KMaxPortNumber)
       
   152 		{
       
   153 		LOG2(_L8("\tTRYING: port %d (PC COM Port %d)"), portNo, portNo + 1);
       
   154 		ret = iPort->Open(portNo);
       
   155 		
       
   156 		if(ret == KErrNone || ret == KErrAlreadyExists)
       
   157 			{
       
   158 			if(CheckHardwareConnected())
       
   159 				{
       
   160 				LOG2(_L8("\tUSING: port %d (PC COM Port %d)"), portNo, portNo + 1);
       
   161 				// Exit the loop, a port has been opened.
       
   162 				break;
       
   163 				}
       
   164 			else 
       
   165 				{
       
   166 				iPort->Close();	// close it - there was no HW there...
       
   167 				}
       
   168 			}
       
   169 		portNo++;  // try the next port
       
   170 		}
       
   171 	
       
   172 	if(ret != KErrNone && ret != KErrAlreadyExists)
       
   173 		{
       
   174 		// A port could not be found.
       
   175 		LEAVEIFERRORL(KErrHardwareNotAvailable);
       
   176 		}
       
   177 	}
       
   178 	
       
   179 #endif // SYMBIAN_INTERNAL_RETRY_BLUETOOTH_PORT_OPEN
       
   180 
       
   181 //Implementation of pure virtuals from CHCTLBase
       
   182 EXPORT_C TAny* CHCTLUartBase::Interface(TUid aUid)
       
   183 	{
       
   184 	TAny* ret = NULL;
       
   185 	switch(aUid.iUid)
       
   186 		{
       
   187 		case KHCTLInterfaceUid:
       
   188 			ret = reinterpret_cast<TAny*>(static_cast<MHCTLInterface*>(this));
       
   189 			break;
       
   190 
       
   191 		default:
       
   192 			break;
       
   193 		};
       
   194 
       
   195 	return ret;
       
   196 	}
       
   197 
       
   198 EXPORT_C void CHCTLUartBase::BaseConstructL(const TDesC& aIniFileName)
       
   199 	{
       
   200 	LOG_FUNC
       
   201 	
       
   202 	_LIT(KSection, "hctl");
       
   203 	_LIT(KVarPort, "port");
       
   204 	_LIT(KVarBaudRate, "baud_rate");
       
   205 	_LIT(KVarPwrCtrlMode, "pwr_ctrl_mode");
       
   206 	#ifdef SYMBIAN_INTERNAL_RETRY_BLUETOOTH_PORT_OPEN
       
   207 	_LIT(KVarScanPorts, "scan_ports");
       
   208 	#endif // SYMBIAN_INTERNAL_RETRY_BLUETOOTH_PORT_OPEN
       
   209 
       
   210 	// Create HCI Utility library
       
   211 	CHciUtil* hciUtil = CHciUtil::NewL(aIniFileName);
       
   212 	CleanupStack::PushL(hciUtil);
       
   213 	
       
   214 	hciUtil->OpenIniFileL();
       
   215 
       
   216 	TUint portNumber = hciUtil->GetValueFromFileL(KSection, KVarPort);
       
   217 	TUint baudRate = hciUtil->GetValueFromFileL(KSection, KVarBaudRate);
       
   218 	
       
   219 	// we don't want to leave if the param is not present. just consider
       
   220 	// the default value as true 
       
   221 	TRAPD(err, iPowerCtrlMode = static_cast<TPowerControlDetectionMode>(hciUtil->GetValueFromFileL(KSection, KVarPwrCtrlMode)));
       
   222 	if (err != KErrNone)
       
   223 		{
       
   224 		iPowerCtrlMode = EPwrCtrlCTSTimedLow;	// keeps back compatibility
       
   225 		}
       
   226 	
       
   227 #ifdef SYMBIAN_INTERNAL_RETRY_BLUETOOTH_PORT_OPEN
       
   228 	TBool scanPorts = EFalse;
       
   229 	TRAP(err, scanPorts = static_cast<TBool>(hciUtil->GetValueFromFileL(KSection, KVarScanPorts)));
       
   230 	if(err != KErrNone)
       
   231 		{
       
   232 		scanPorts = EFalse; // default to off because of stack boot time impact
       
   233 		}
       
   234 #endif // SYMBIAN_INTERNAL_RETRY_BLUETOOTH_PORT_OPEN
       
   235 	
       
   236 	// Remove the HCI UTIL instance. 
       
   237 	CleanupStack::PopAndDestroy();
       
   238 	
       
   239 	// Allocate the RBtBusDevComm port object
       
   240 	iPort = new (ELeave) RBtBusDevComm;
       
   241 	
       
   242 #ifdef SYMBIAN_INTERNAL_RETRY_BLUETOOTH_PORT_OPEN
       
   243 	if(scanPorts)
       
   244 		{
       
   245 		ScanAndOpenPortL(portNumber);
       
   246 		}
       
   247 	else
       
   248 #endif // SYMBIAN_INTERNAL_RETRY_BLUETOOTH_PORT_OPEN
       
   249 		{
       
   250 		OpenPortL(portNumber);
       
   251 		}
       
   252 	
       
   253 	SetPortBaudRateL(baudRate);
       
   254 
       
   255 	// Perform any HCTL specific initialisation. 
       
   256 	PortOpenedL();
       
   257 	}
       
   258 
       
   259 EXPORT_C void CHCTLUartBase::SetPortBaudRateL(TUint32 aBaudRate)
       
   260 	{	
       
   261 	LOG_FUNC
       
   262 
       
   263 	TCommConfig configPkg;
       
   264 	iPort->Config(configPkg);
       
   265 	TCommConfigV01& config = configPkg(); //Get reference to TCommConfig iConfig
       
   266 
       
   267 	switch(aBaudRate)
       
   268 		{
       
   269 		case 57600:
       
   270 			config.iRate = EBps57600;
       
   271 			break;
       
   272 
       
   273 		case 115200:
       
   274 			config.iRate = EBps115200;
       
   275 			break;
       
   276 
       
   277 		case 230400:
       
   278 			config.iRate = EBps230400;
       
   279 			break;
       
   280 
       
   281 		case 460800:
       
   282 			config.iRate = EBps460800;
       
   283 			break;
       
   284 
       
   285 		case 576000:
       
   286 			config.iRate = EBps576000;
       
   287 			break;
       
   288 
       
   289 		case 750000:
       
   290 			config.iRate = EBpsSpecial;
       
   291 			config.iSpecialRate=0; // 750000;
       
   292 			break;
       
   293 
       
   294 		case 1152000:
       
   295 			config.iRate = EBps1152000;
       
   296 			break;
       
   297 
       
   298 		case 921600:
       
   299 			config.iRate = EBps921600;
       
   300 			break;
       
   301 
       
   302 		case 1843200:
       
   303 			config.iRate = EBpsSpecial;
       
   304 			config.iSpecialRate=1; // 1843200;
       
   305 			break;
       
   306 
       
   307 		case 3686400:
       
   308 		case 3692300:
       
   309 		case 3600000:
       
   310 			config.iRate = EBpsSpecial;
       
   311 			config.iSpecialRate=2; // 3686400;
       
   312 			break;
       
   313 
       
   314 		case 3000000:
       
   315 			config.iRate = EBpsSpecial;
       
   316 			config.iSpecialRate = 3;
       
   317 			break;
       
   318 
       
   319 		default:
       
   320 			// Use default rate in case of error
       
   321 			config.iRate = EBps115200;
       
   322 			break;
       
   323 		};
       
   324 	
       
   325 	// Update the port configuration.
       
   326 	LEAVEIFERRORL(iPort->SetConfig(configPkg));
       
   327 	}
       
   328 
       
   329 // Accessor method for the port
       
   330 EXPORT_C RBusDevComm& CHCTLUartBase::Port()
       
   331 	{
       
   332 	// No check for a NULL iPort is needed because BaseConstructL will Leave if we
       
   333 	// fail to allocate the port object
       
   334 	return *iPort;
       
   335 	}
       
   336 
       
   337 EXPORT_C CHCTLUartBase::TPowerControlDetectionMode CHCTLUartBase::PowerCtrlMode() const
       
   338 	{
       
   339 	return iPowerCtrlMode;
       
   340 	}