iphone-charge

iPhone/iPod TouchLinux から充電できるようにするプログラムです。
本来これには http://mattcolyer.com/projects/iphone-module/ の "iPhone Module" で対応可能ですが、userspace でできるように移植したものがこのプログラムとなっています*1

ダウンロード (Download):http://www.autch.net/online/files/iphone-charge_20071117.zip

コンパイル

libusb と libusb-dev が入った状態で make するだけ。

実行

iPhone/iPod Touch を USB で接続してから、sudo ./iphone-charge とするだけ。su か sudo しないと失敗します。
バイスを見つけると "Found iPod Touch or iPhone, sending magic command" とか言いますので充電状態が続くことを確認してください。
複数デバイスの接続も多分サポートします。コードは書いてありますが試したことはありません。

ライセンス

"iPhone Module" が GPL なので、このプログラムも GPL に従います。

ソース

英語圏からぐぐってヒットするように。

/*
 * Send a magic command to iPhone/iPod Touch to keep it charging while
 * connected.  libusb/userspace version.
 *
 * Compiling: Install libusb and libusb-dev, then run 'make'
 *
 * Usage: Connect your iPhone/iPod Touch, start a shell, then run:
 * $ sudo ./iphone-charge
 *
 * Copyright (c) 2007 Autch <autch@autch.net>, http://www.autch.net/
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, version 2.
 *
 * Derived from "iPhone Module"[1], licensed under GPLv2.
 * "iPhone Module" is copyrighted as following:
 * > Copyright (C) 2007 Greg Kroah-Hartman <gregkh@suse.de>
 * > Copyright (C) 2007 Matt Colyer <matt@colyer.name>
 * >
 * > This program is free software; you can redistribute it and/or
 * > modify it under the terms of the GNU General Public License as
 * > published by the Free Software Foundation, version 2.
 *
 * [1] http://mattcolyer.com/projects/iphone-module/
 */

#define _POSIX_C_SOURCE 199309
#include <usb.h>
#include <stdio.h>
#include <time.h>

#define USB_VEN_APPLE       (0x05ac)
#define USB_PROD_IPHONE     (0x1290)
#define USB_PROD_IPOD_TOUCH (0x1291)

#define TRIALS              3
#define TRIAL_SLEEP         100

int find_and_try();
int send_magic_msg(struct usb_device* dev);
void Sleep(unsigned int msec);

int main()
{
  int trials;

  usb_init();
  usb_find_busses();

  for(trials = TRIALS; trials > 0; trials--)
  {
    if(find_and_try() > 0) break;
    Sleep(TRIAL_SLEEP);
  }

  return 0;
}

int find_and_try()
{
  struct usb_bus *bus = NULL;
  struct usb_device *dev = NULL;
  int found = 0;

  usb_find_devices();
  for(bus = usb_get_busses(); bus; bus = bus->next)
  {
    for(dev = bus->devices; dev; dev = dev->next)
    {
      if(dev->descriptor.idVendor == USB_VEN_APPLE
         && (dev->descriptor.idProduct == USB_PROD_IPOD_TOUCH
             || dev->descriptor.idProduct == USB_PROD_IPHONE))
      {
        send_magic_msg(dev);
        found++;
      }
    }
  }

  return found;
}

int send_magic_msg(struct usb_device* dev)
{
  usb_dev_handle* hdev;
  unsigned char dummy_buffer[2];

  printf("Found iPod Touch or iPhone, sending magic command\n");
  hdev = usb_open(dev);
  usb_set_configuration(hdev, 3);
  usb_control_msg(hdev, 0x40, 0x40, 0x6400, 0, (char*)dummy_buffer, 0, 100);
  usb_close(hdev);

  return 0;
}

void Sleep(unsigned int msec)
{
  struct timespec req;
  struct timespec rem;

  req.tv_sec = msec / 1000;
  req.tv_nsec = (msec % 1000) * 1000000;

  nanosleep((const struct timespec *)&req, &rem);
}

*1:どのみち root は必要なんですが