1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/api/serial/serial_io_handler.h" 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h" 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/message_loop/message_loop.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace extensions { 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SerialIoHandler::SerialIoHandler() 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : file_(base::kInvalidPlatformFileValue), 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_read_buffer_len_(0), 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_write_buffer_len_(0) { 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SerialIoHandler::~SerialIoHandler() { 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SerialIoHandler::Initialize(base::PlatformFile file, 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ReadCompleteCallback& read_callback, 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const WriteCompleteCallback& write_callback) { 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(file_, base::kInvalidPlatformFileValue); 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) file_ = file; 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) read_complete_ = read_callback; 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) write_complete_ = write_callback; 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InitializeImpl(); 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SerialIoHandler::Read(int max_bytes) { 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!IsReadPending()); 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_read_buffer_ = new net::IOBuffer(max_bytes); 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_read_buffer_len_ = max_bytes; 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) read_canceled_ = false; 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AddRef(); 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ReadImpl(); 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SerialIoHandler::Write(const std::string& data) { 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!IsWritePending()); 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_write_buffer_ = new net::IOBuffer(data.length()); 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_write_buffer_len_ = data.length(); 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memcpy(pending_write_buffer_->data(), data.data(), pending_write_buffer_len_); 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) write_canceled_ = false; 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AddRef(); 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WriteImpl(); 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SerialIoHandler::ReadCompleted(int bytes_read, 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) api::serial::ReceiveError error) { 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(IsReadPending()); 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) read_complete_.Run(std::string(pending_read_buffer_->data(), bytes_read), 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error); 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_read_buffer_ = NULL; 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_read_buffer_len_ = 0; 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Release(); 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SerialIoHandler::WriteCompleted(int bytes_written, 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) api::serial::SendError error) { 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(IsWritePending()); 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) write_complete_.Run(bytes_written, error); 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_write_buffer_ = NULL; 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_write_buffer_len_ = 0; 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Release(); 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool SerialIoHandler::IsReadPending() const { 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return pending_read_buffer_ != NULL; 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool SerialIoHandler::IsWritePending() const { 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return pending_write_buffer_ != NULL; 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SerialIoHandler::CancelRead(api::serial::ReceiveError reason) { 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (IsReadPending()) { 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) read_canceled_ = true; 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) read_cancel_reason_ = reason; 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CancelReadImpl(); 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SerialIoHandler::CancelWrite(api::serial::SendError reason) { 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(CalledOnValidThread()); 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (IsWritePending()) { 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) write_canceled_ = true; 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) write_cancel_reason_ = reason; 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CancelWriteImpl(); 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SerialIoHandler::QueueReadCompleted(int bytes_read, 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) api::serial::ReceiveError error) { 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::MessageLoop::current()->PostTask( 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FROM_HERE, base::Bind(&SerialIoHandler::ReadCompleted, this, 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bytes_read, error)); 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SerialIoHandler::QueueWriteCompleted(int bytes_written, 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) api::serial::SendError error) { 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::MessageLoop::current()->PostTask( 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FROM_HERE, base::Bind(&SerialIoHandler::WriteCompleted, this, 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bytes_written, error)); 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace extensions 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 121