[cpp]
USB On-The-Go and Embedded Host
Virtually every portable device now uses USB for PC connectivity. As these products increase in popularity, there is a growing need for them to communicate both with USB peripherals and directly with each other when a PC is not available. There is also an increase in the number of other, non-PC hosts (Embedded Hosts) which support USB in order to connect to USB peripherals.
先看android VOLD:
[cpp]
root@ubuntu:/cm10/4.2/system/vold# ls
[cpp]
Android.mk Devmapper.h logwrapper.c Process.cpp Volume.cpp
Asec.h DirectVolume.cpp Loop.cpp Process.h Volume.h
CleanSpec.mk DirectVolume.h Loop.h ResponseCode.cpp VolumeManager.cpp
CommandListener.cpp Ext4.cpp main.cpp ResponseCode.h VolumeManager.h
CommandListener.h Ext4.h NetlinkHandler.cpp tests Xwarp.cpp
cryptfs.c Fat.cpp NetlinkHandler.h vdc.c Xwarp.h
cryptfs.h Fat.h NetlinkManager.cpp VoldCommand.cpp
Devmapper.cpp hash.h NetlinkManager.h VoldCommand.h
简单梳理一下,在vold中处理otg,将需要与PC机共享的磁盘设备写到一个文件里面,作为一个标志,再广播给上层,传播一个大容量存储的状态。
查看源码:
[cpp]
vi ./CommandListener.cpp
[cpp]
#define MASS_STORAGE_FILE_PATH "/sys/class/android_usb/android0/f_mass_storage/lun/file" //标志文件
1、连接PC部分。
在该函数中做分支解析:
[cpp]
int CommandListener::VolumeCmd::runCommand(SocketClient *cli,
int argc, char **argv)
[cpp]
else if (!strcmp(argv[1], "share")) {
if (argc != 4) {
cli->sendMsg(ResponseCode::CommandSyntaxError,
"Usage: volume share <path> <method>", false);
return 0;
}
rc = vm->shareVolume(argv[2], argv[3]); //进入shareVolume函数对各状态进行判断,其中可判断INAND或SD卡状态,如果不存在或者忙状态,则返回错误值。
具体看看shareVolume函数如何实现:
[cpp]
vi VoldCommand.cpp
[cpp]
int VolumeManager::shareVolume(const char *label, const char *method) {
Volume *v = lookupVolume(label);
if (!v) {
errno = ENOENT;
return -1;
}
/*
* Eventually, we'll want to support additional share back-ends,
* some of which may work while the media is mounted. For now,
* we just support UMS
*/
if (strcmp(method, "ums")) {
errno = ENOSYS;
return -1;
}
if (v->getState() == Volume::State_NoMedia) {
errno = ENODEV;
return -1;
}
if (v->getState() != Volume::State_Idle) {
// You need to unmount manually befoe sharing
errno = EBUSY;
return -1;
}
if (mVolManagerDisabled) {
errno = EBUSY;
return -1;
}
/*getShareDevice函数直接返回SD卡的设备号,部分版本该函数为getDiskDeve*/
dev_t d = v->getShareDevice();
if ((MAJOR(d) == 0) && (MINOR(d) == 0)) {
// This volume does not support raw disk access
errno = EINVAL;
return -1;
}
int fd;
char nodepath[255];
snprintf(nodepath,
sizeof(nodepath), "/dev/block/vold/%d:%d",
MAJOR(d), MINOR(d));
/*重要的文件读写函数在这里体现,PC机欲识别android设备中的存储器,需将SD卡的设备节点路径写到MASS_STORAGE_FILE_PATH 文件中去,打开大容量存储功能*/
if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {
SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
return -1;
}
if (write(fd, nodepath, strlen(nodepath)) < 0) {
SLOGE("Unable to write to ums lunf
补充:移动开发 , Android ,