/// <summary> /// The actual read thread /// </summary> /// <param name="service">Service instance to access public members</param> public void ReadProc(object service) { int byteRead; // We read one byte at a time bool twoByteFlag = false; // Set if we've read the first byte of a two-byte sequence int secondByte = 0; // The second byte of the sequence (may denoted device type) Message msg; serviceContext = (RemoteCommunicationService)service; try { while ((byteRead = inputStream.ReadByte()) >= 0) { AppLog.Log("RCS-ReadProc; reading: " + byteRead.ToString()); switch (serviceContext.serviceState) { case AppConst.ActivityState.idle: // We shouldn't actually get here as the read thread should only be started in connected state serviceContext.lastReport = 0; twoByteFlag = false; break; case AppConst.ActivityState.connected: if (twoByteFlag) // We are connected, but the handshake is in progress. Check if we're reading the second byte of a sequence { secondByte = byteRead; twoByteFlag = false; if (secondByte < 128) { UpdateState(AppConst.ActivityState.synced); serviceContext.lastReport = 0; } break; } if (byteRead < 127) // As soon as we have a byte with the top bit clear, the handshake is complete (may occur immediately on reconnecting to device) { UpdateState(AppConst.ActivityState.synced); serviceContext.lastReport = 0; twoByteFlag = false; } else if (byteRead == 128) // If we've received a byte with the top bit set, send "key up" message to handshake the recorder { twoByteFlag = true; msg = serviceContext.handler.ObtainMessage(); msg.What = (int)AppConst.MsgPrio.low; msg.Data.PutString(BundleConst.bundleCmdTag, BundleConst.cmdSend); msg.Data.PutByteArray(BundleConst.bundleDataTag, promptSequence); serviceContext.handler.SendMessage(msg); } break; case AppConst.ActivityState.synced: // If top bit set, the handshake has been lost (eg bluetooth device has been unplugged from recorder) if (byteRead > 127) { UpdateState(AppConst.ActivityState.connected); twoByteFlag = true; } else { twoByteFlag = false; if (serviceContext.lastReport != byteRead) { SendData(byteRead); } serviceContext.lastReport = byteRead; } break; } } } // Most likely called when the other thread closes the bluetooth socket on disconnecting catch (Throwable e) { AppLog.Log("RCS-ReadProc; exception: " + e.ToString()); try { inputStream.Close(); } catch (Throwable) { AppLog.Log("RCS-ReadProc; stream close exception: " + e.ToString()); } } }
/// <summary> /// Constructor for ServiceHandler /// </summary> /// <param name="looper">The associated looper which the base class needs</param> /// <param name="serviceContext">The instance for the service so we can access non-static members</param> public ServiceHandler(Looper looper, RemoteCommunicationService serviceContext) : base(looper) { this.serviceContext = serviceContext; }