#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <asm/types.h> //该头文件需要放在netlink.h前面防止编译出现__kernel_sa_family未定义 #include <sys/socket.h> #include <sys/epoll.h> #include <linux/netlink.h> #include<time.h> #include "common.h" #include "list.h" #include "usb_hotplug.h" #include "tcp_client.h" #include "logw.h" char g_productstr[20] = {0}; int g_iFileReadable = 0; int g_iUsbhotplugSocket; EVENTINFO usbev; struct sockaddr_nl g_stUsbSockAddr; USB_LIST usblist; char* usbhotplug_getdevpath(char *str) { char *strtmp1 = str; char *strtmp2; char *path; int i,len = 0; while(*strtmp1++ != '@'); strtmp2 = strtmp1; while(*strtmp1++ != '\n') len++; /*获取devpath路径*/ path = (char*)malloc((len+1) * sizeof(char)); for(i = 0; i <= len; i++) { path[i] = strtmp2[i]; } path[len] = '\0'; return path; } int usbhotplug_getparamvalue(char *path, char *val) { FILE * fp; int i; fp=fopen(path,"r"); if(NULL == fp) { LOG(DEBUG, "usb get para err.\n"); return ERROR_FAILED; } fgets(val, 100, fp); for(i=0;i<strlen(val);i++) if(*(val+i)=='\n') val[i]='\0'; //printf("%s",val); fclose(fp); return ERROR_SUCCESS; } void usbhotplug_inmsg_proc(char *path) { USB_LIST *pnode; USBINFO_S *pinfo; char *parent_path; int iIndex; int m=0, n=0; int ilen = strlen(path); int parent_len = strlen(path); char result_str[DATABUFCOMLEN] = "\0"; if(NULL == path) { LOG(DEBUG, "path error.\n"); return; } pnode = (USB_LIST*)malloc(sizeof(USB_LIST)); pinfo = (USBINFO_S *)malloc (sizeof(USBINFO_S)); while(path[--parent_len] != '/'); parent_path = malloc((parent_len + 1) * sizeof(char)); memset(parent_path, 0, parent_len+1); for(iIndex = 0; iIndex < parent_len; iIndex++) { parent_path[iIndex] = path[iIndex]; } sprintf(pinfo->path_productname, path); /*接口协议号路径*/ sprintf(pinfo->path_interfaceprotocol, path); strcat(pinfo->path_interfaceprotocol, "/bInterfaceProtocol"); usbhotplug_getparamvalue(pinfo->path_interfaceprotocol, pinfo->interfaceprotocol); /*设备名称*/ sprintf(pinfo->path_productname , parent_path); strcat(pinfo->path_productname, "/product"); usbhotplug_getparamvalue(pinfo->path_productname, pinfo->productname); /*厂商名称*/ sprintf(pinfo->path_manufacturername , parent_path); strcat(pinfo->path_manufacturername, "/manufacturer"); usbhotplug_getparamvalue(pinfo->path_manufacturername, pinfo->manufacturername); /*设备编号*/ sprintf(pinfo->path_productid , parent_path); strcat(pinfo->path_productid, "/idProduct"); usbhotplug_getparamvalue(pinfo->path_productid, pinfo->productid); /*厂商编号*/ sprintf(pinfo->path_vendorid , parent_path); strcat(pinfo->path_vendorid, "/idVendor"); usbhotplug_getparamvalue(pinfo->path_vendorid, pinfo->vendorid); /*接口编号*/ for(iIndex = parent_len+1; iIndex < ilen; iIndex++) { if(path[iIndex] == ':') n = m; pnode->interfacenum[m++] = path[iIndex]; } pnode->interfacenum[m] = '\0'; //printf("interfacenum %s\n", pnode->interfacenum); /*USB接口号*/ for(iIndex = 0; iIndex < n; iIndex++) { pinfo->usb_interfacenum[iIndex] = pnode->interfacenum[iIndex]; } pinfo->usb_interfacenum[n] = '\0'; //printf("usb_interfacenum %s\n", pinfo->usb_interfacenum); snprintf(result_str, DATABUFCOMLEN, "{%s} {%s} {%s} {%s} {%s} {<%s@%s>}", pinfo->usb_interfacenum, pinfo->productname, pinfo->manufacturername, pinfo->productid, pinfo->vendorid, pnode->interfacenum, pinfo->interfaceprotocol); //printf("%s\n", result_str); tcpclient_eventsend(result_str, EVENT_GENERAL, EVENT_SUBTYPE_USBIN); /*保存当前usb节点信息到链表*/ pnode->info = pinfo; list_add_tail(&(pnode->list), &(usblist.list)); } void usbhotplug_outmsg_proc(char *path) { USB_LIST *node; char szintername[20] = "\0"; int ilen = strlen(path); int parent_len = strlen(path); int iIndex; int m = 0; char result_str[DATABUFCOMLEN] = "\0"; if(NULL == path) { LOG(DEBUG, "path error.\n"); return; } while(path[--parent_len] != '/'); for(iIndex = parent_len+1; iIndex < ilen; iIndex++) { szintername[m++] = path[iIndex]; } szintername[m] = '\0'; list_for_each_entry(node, &usblist.list, list) { if(strcmp(node->interfacenum, szintername) == 0) break; } if('\0' == node->interfacenum[0] ) { sprintf(result_str, "{%s} {%s} {%s} {%s} {%s} {<%s@%s>}", "unknown", "unknown", "unknown", "unknown", "unknown", szintername, "unknown"); LOG(INFO, "%s\n", result_str); return; } snprintf(result_str, DATABUFCOMLEN, "usb remove : {%s} {%s} {%s} {%s} {%s} {<%s@%s>}", node->info->usb_interfacenum, node->info->productname, node->info->manufacturername, node->info->productid, node->info->vendorid, node->interfacenum, node->info->interfaceprotocol); //printf("%s\n", result_str); tcpclient_eventsend(result_str, EVENT_INFORM, EVENT_SUBTYPE_USBOUT); list_del(&node->list); free(node->info); free(node); } void usbhotplug_recv_proc() { int iLength = 0; int iIndex; char *product_str; char *pcaction_str; char *pcsubsystem_str; char *pcdevpath; char szsysdevpath[100] = "\0"; struct iovec iov; struct msghdr stmsg; char szbuf[4096]; memset(&stmsg,0,sizeof(stmsg)); iov.iov_base=(void *)szbuf; iov.iov_len=sizeof(szbuf); stmsg.msg_name=(void *)&g_stUsbSockAddr; stmsg.msg_namelen=sizeof(g_stUsbSockAddr); stmsg.msg_iov=&iov; stmsg.msg_iovlen=1; iLength=recvmsg(g_iUsbhotplugSocket,&stmsg,0); if(0 >= iLength) { LOG(DEBUG, "receive error\n"); } if(iLength < 32 || iLength > sizeof(szbuf)) { LOG(DEBUG, "invalid message"); } usleep(500); for(iIndex = 0; iIndex < iLength; iIndex++ ) if(*(szbuf + iIndex) == '\0') szbuf[iIndex] = '\n'; if((pcaction_str = strstr(szbuf,"add@")) && (product_str=strstr(szbuf,"PRODUCT")) && (pcsubsystem_str = strstr(szbuf,"usb_interface"))) { pcdevpath = usbhotplug_getdevpath(pcaction_str); sprintf(szsysdevpath, "/sys"); strncat(szsysdevpath, pcdevpath, sizeof(szsysdevpath) - 5); LOG(INFO, "sysdevpath %s\n", szsysdevpath); usbhotplug_inmsg_proc(szsysdevpath); } if((pcaction_str = strstr(szbuf,"remove@")) && (product_str=strstr(szbuf,"PRODUCT")) && (pcsubsystem_str = strstr(szbuf,"usb_interface"))) { pcdevpath = usbhotplug_getdevpath(pcaction_str); sprintf(szsysdevpath, "/sys"); strncat(szsysdevpath, pcdevpath, sizeof(szsysdevpath) - 5); //printf("sysdevpath %s\n", szsysdevpath); usbhotplug_outmsg_proc(szsysdevpath); } } int init_usbhotplug(int epollfd) { struct epoll_event eventItem; /*初始化usb链表*/ INIT_LIST_HEAD(&usblist.list); usblist.interfacenum[0] = '\0'; memset(&g_stUsbSockAddr,0,sizeof(g_stUsbSockAddr)); g_stUsbSockAddr.nl_family=AF_NETLINK; g_stUsbSockAddr.nl_groups=NETLINK_KOBJECT_UEVENT; g_stUsbSockAddr.nl_pid = 0;/*getpid(); both is ok*/ g_iUsbhotplugSocket=socket(AF_NETLINK,SOCK_RAW,NETLINK_KOBJECT_UEVENT); if(g_iUsbhotplugSocket==-1) LOG(ERROR, "socket creating failed:%s\n",strerror(errno)); if(bind(g_iUsbhotplugSocket,(struct sockaddr *)&g_stUsbSockAddr,sizeof(g_stUsbSockAddr))==-1) LOG(ERROR, "bind error:%s\n",strerror(errno)); eventItem.events = EPOLLIN; eventItem.data.fd = g_iUsbhotplugSocket; epoll_ctl(epollfd, EPOLL_CTL_ADD, g_iUsbhotplugSocket, &eventItem); usbev.fd = g_iUsbhotplugSocket; usbev.pfcb = usbhotplug_recv_proc; regeister_callback(USBMODULE, &usbev); return 0; }