当前位置: 首页 > news >正文

大型网站的空间创意广告

大型网站的空间,创意广告,淘宝做海淘产品 网站折扣变化快,wordpress网站推翻重建最近一直在处理hid 数据需求,简而言之就是两台设备直接可以通过usb 线互相传递数据。 项目架构 为什么Device 端要采用HID(人机接口设备)的方式发送和接收数据呢? 主要是速度快,举个例子,就是鼠标移动&am…

最近一直在处理hid 数据需求,简而言之就是两台设备直接可以通过usb 线互相传递数据。

项目架构

为什么Device 端要采用HID(人机接口设备)的方式发送和接收数据呢?

主要是速度快,举个例子,就是鼠标移动,屏幕可以及时响应,用的也是这种协议。

因为Host端底层我们控制不了,不能保证都支持Hid 协议,所以Host 端采用跨平台方案,libusb 协议。

Liusb 网上介绍的很多啦,可以运行在各个平台,windows ,android.linux,是一种理想中的跨平台数据传输方案。

项目主要功能

1,sensor数据传输

2,TP 数据传输(按键传输同理)

项目主要技术点

1,TP数据监听

2,sensor数据监听

3,hid 数据传输丢失问题

4,HID 节点生成监听

5,开机启动native 服务处理数据

6,selinux 权限问题

技术实现

代码结构

TP数据监听

驱动所有的滑动 和 按键 上报都是通过节点的方式,不同平台节点有所差异,需要和驱动沟通。我试验的平台节点是:

#define INPUT_KEY_NODE "/dev/input/event1"
#define INPUT_TP_NODE "/dev/input/event3"

所以监听这两个就行了,我们这里采用的是poll 的方式,有数据的时候会回调,没有的话会阻塞

主要代码

void HidReceiver::listenThread()
{struct pollfd fds[IN_FILES];fds[0].events = POLLIN;fds[1].events = POLLIN;fds[2].events = POLLIN;int result;char buff[512];
//    sleep(1);LOGD("hid open");hid_fd = open(DEVICE_NODE, O_RDWR | O_NONBLOCK);int key_fd =  open(INPUT_KEY_NODE, O_RDWR | O_NONBLOCK);int tp_fd =  open(INPUT_TP_NODE, O_RDWR | O_NONBLOCK);LOGD("nod %d,%d,%d",hid_fd,key_fd,tp_fd);fds[0].fd = hid_fd;fds[1].fd = key_fd;fds[2].fd = tp_fd;unsigned char data[sizeof(input_event)];input_event dev_data;while(1){result = poll(fds, IN_FILES, -1);if (result == 0) {LOGD("Poll timeout");} else if(result > 0){if ((fds[0].revents & POLLIN)){ int size = read(fds[0].fd, buff, sizeof(buff));if(size > 0){process_event(buff);}}if ((fds[1].revents & POLLIN)){ int size = read (fds[1].fd, (unsigned char*)data, sizeof(input_event));LOGD("size:%d", size);memcpy(&dev_data, data, sizeof(input_event));LOGD("Keyevent size:%d", dev_data.type);// sensordata.sensorType = 0x104;// sensordata.ievent = dev_data;// process_event(sensordata);}if ((fds[2].revents & POLLIN)){ int size = read (fds[2].fd, (unsigned char*)data, sizeof(input_event));memcpy(&dev_data, data, sizeof(input_event));#if 0LOGD("abs size:%d", dev_data.type);if (dev_data.type == EV_ABS){if (dev_data.code == ABS_MT_POSITION_X){x = dev_data.value;if (x < 0) x = 0;LOGD("rel X:%d", dev_data.value);}else if(dev_data.code == ABS_MT_POSITION_Y){LOGD("\nx=%d,y=%d,dev_data.code=%d\n", x, y,dev_data.code);y = dev_data.value;if (y < 0) y = 0;sensordata.sensorType = 0x104;sensordata.abs_x = x;sensordata.abs_y = y;process_event(sensordata);x = 0;y = 0;}}#endifif (dev_data.type == EV_KEY){LOGD("EV_KEY %d",dev_data.code);switch(dev_data.code){case KEY_KP5://双击case KEY_DASHBOARD://单机case KEY_F17://左滑case KEY_ISO://右滑case KEY_F16://上滑case KEY_CONFIG://下滑sensordata.sensorType = 0x104;sensordata.type = dev_data.type;sensordata.code = dev_data.code;sensordata.value = dev_data.value;sensordata.priority = 3;process_event(sensordata);break;             }}}}    }
} 

代码中DEVICE_NODE  用于监听hid 数据的,这个后面说。

sensor数据监听

void SensorTransfer::listenThread()
{int64_t stamp;LOGD("listenThread");while (m_bListening){ASensorEvent event;while (ASensorEventQueue_getEvents(m_pEvtQue, &event, 1) > 0){stamp = event.timestamp;switch (event.type){// case ASENSOR_TYPE_GYROSCOPE://     printf("GYROSCOPE:(%llu, %f,%f,%f)\n", (unsigned long long)stamp, event.data[0], event.data[1], event.data[2]);//     break;case ASENSOR_TYPE_ACCELEROMETER:// printf("ACCELEROMETER: (%llu, %f,%f,%f)\n", (unsigned long long)stamp, event.data[0], event.data[1], event.data[2]);sensordata.stamp = stamp;sensordata.sensorType = 0x100;sensordata.xvalue = event.data[0];sensordata.yvalue = event.data[1];sensordata.zvalue = event.data[2];saveSensorData(sensordata);sensordata.priority = 1;break;case ASENSOR_TYPE_GRAVITY:// printf("GRAVITY: (%llu, %f,%f,%f)\n", (unsigned long long)stamp, event.data[0], event.data[1], event.data[2]);sensordata.stamp = stamp;sensordata.sensorType = 0x101;sensordata.xvalue = event.data[0];sensordata.yvalue = event.data[1];sensordata.zvalue = event.data[2];sensordata.priority = 1;saveSensorData(sensordata);break;case ASENSOR_TYPE_PROXIMITY:sensordata.stamp = stamp;sensordata.sensorType = 0x102;sensordata.lightvalue = event.data[0];sensordata.priority = 1;saveSensorData(sensordata);break;default:break;}}usleep(1000);}
} 

这个参考的一个博主的方案,主要是通过循环读取native sensor 数据。

监听HID节点删除添加

void HidReceiver::nodWatch(){int length, i = 0;int fd;int wd;char buffer[BUF_LEN];fd = inotify_init();if (fd < 0) {LOGD("inotify_init");}wd = inotify_add_watch(fd, DEV_NODE, IN_CREATE );if (wd < 0) {LOGD("inotify_add_watch");}LOGD("Monitoring directory: %s", DEV_NODE);bool monitor = true;while (monitor) {LOGD("start monitor");length = read(fd, buffer, BUF_LEN);  if (length < 0) {LOGD("read");}  i = 0;LOGD("read %d",length);while (i < length) {struct inotify_event *event = (struct inotify_event *) &buffer[i];LOGD("inotify_event %d",event->len);if (event->len) {LOGD("ievent->mask %d",event->mask);if (event->mask & IN_CREATE) {LOGD("Created: %s", event->name);if(strcmp(event->name,"hidg0") == 0){LOGD("Created: hidg0");monitor = false;startListen();inotify_rm_watch(fd, wd);return;}} else if (event->mask & IN_DELETE) {LOGD("Deleted: %s", event->name);} else if (event->mask & IN_MODIFY) {LOGD("Modified: %s", event->name);} else if (event->mask & IN_MOVED_FROM) {LOGD("Moved from: %s", event->name);} else if (event->mask & IN_MOVED_TO) {LOGD("Moved to: %s", event->name);}}i += EVENT_SIZE + event->len;}}
}

Hid 数据传输和数据丢失问题

hid 数据怎么传,其实很简单,写节点就可以了,但是数据量太大的时候,会出现写节点失败,同时,按键或者TP 等数据,也会丢失,sensor 数据丢失感知倒不是很大,但是按键和触摸这些传输失败,Host端就无法响应,体验会很差。

目前采用的方案是

Bufferqueue + 延时 解决HID 数据丢失的问题(生产者消费者模式)

priority_queue  解决用户主动操作的数据优先级问题,主要是TP 和 按键,保证优先响应

主要代码:

消费者

// 消费者线程,读取队列中的数据并发送
void SensorTransfer::consumer() {while (true) {std::unique_lock<std::mutex> lock(queueMutex);dataCondition.wait(lock, [this] { return !bufferQueue.empty(); });// if (!bufferQueue.empty())//     break; // 程序结束if(!bufferQueue.empty()){sensor_data data = bufferQueue.top();// 发送数据到 HID 设备int written = write(hid_fd,&data,sizeof(struct sensor_data));if(written >=0){bufferQueue.pop();}else{//LOGD("rewrite data result fail");std::this_thread::sleep_for(std::chrono::milliseconds(1)); // 控制发送速率}if(data.sensorType == 259){LOGD("consumer sn");std::this_thread::sleep_for(std::chrono::milliseconds(5)); }if(data.sensorType == 260){LOGD("consumer KEY");std::this_thread::sleep_for(std::chrono::milliseconds(5)); }}else{LOGD("consumer 等待");}}
}

生产者

int SensorTransfer::saveSensorData(sensor_data data) {//std::lock_guard<std::mutex> lock(queueMutex);if (bufferQueue.size() < MAX_QUEUE) { // 限制队列最大长度bufferQueue.push(data);sensor_data topdata = bufferQueue.top();if(topdata.sensorType != 259&&topdata.sensorType != 260){dataCondition.notify_one(); // 通知消费者线程}}else{LOGD("buffer is full");}return 0;
}

selinux 添加

这个是老一套了,之前也写过文章,可以参考这里直接贴上主要权限

新增hidtransfer.te

type hidtransfer, domain,mlstrustedsubject;
typeattribute hidtransfer coredomain;
type hidtransfer_exec, system_file_type, exec_type, file_type;
binder_use(hidtransfer)
init_daemon_domain(hidtransfer)allow hidtransfer system_server:unix_stream_socket {read write};
allow hidtransfer tty_device:chr_file {write read getattr};
allow hidtransfer hid_device:chr_file { read getattr open ioctl write};
allow hidtransfer device:dir read;
allow hidtransfer system_server:binder call;
allow hidtransfer tty_device:chr_file ioctl;
allow hidtransfer serialno_prop:file { map getattr open read};
allow hidtransfer permission_service:service_manager find;
allow hidtransfer sensorservice_service:service_manager find;
allow hidtransfer input_device:chr_file { read write open };
allow hidtransfer input_device:dir { search };
allow hidtransfer device:dir watch;
allow hidtransfer system_server:fd use;

file_contexts

/system/bin/hidtransfer u:object_r:hidtransfer_exec:s0
/dev/hidg0 u:object_r:hid_device:s0

device.te

type hid_device,dev_type;

参考:

1.Android Native Sensor(C++)实例_sensor hal 陀螺仪读取数据实现代码-CSDN博客


文章转载自:
http://dinncoshawmist.tpps.cn
http://dinncounexhausted.tpps.cn
http://dinncoharmonium.tpps.cn
http://dinncocowgrass.tpps.cn
http://dinncospeechcraft.tpps.cn
http://dinncomechanoreceptor.tpps.cn
http://dinncomononucleate.tpps.cn
http://dinncosponsion.tpps.cn
http://dinncomolto.tpps.cn
http://dinncopate.tpps.cn
http://dinncojoypop.tpps.cn
http://dinncocummer.tpps.cn
http://dinncopetrophysics.tpps.cn
http://dinncodr.tpps.cn
http://dinncountutored.tpps.cn
http://dinncocresyl.tpps.cn
http://dinncogastronome.tpps.cn
http://dinncohoratia.tpps.cn
http://dinncofoundryman.tpps.cn
http://dinncoapprovable.tpps.cn
http://dinncoimagic.tpps.cn
http://dinncogemmule.tpps.cn
http://dinncovehicular.tpps.cn
http://dinncokarateka.tpps.cn
http://dinncoschwarz.tpps.cn
http://dinncoadmensuration.tpps.cn
http://dinncogenbakusho.tpps.cn
http://dinncoelate.tpps.cn
http://dinncotastemaker.tpps.cn
http://dinncomalapert.tpps.cn
http://dinncounkind.tpps.cn
http://dinncopusan.tpps.cn
http://dinncoterrene.tpps.cn
http://dinncokunlun.tpps.cn
http://dinncotrustily.tpps.cn
http://dinncobulldoze.tpps.cn
http://dinncoheiau.tpps.cn
http://dinncoviremia.tpps.cn
http://dinncocasuistic.tpps.cn
http://dinncoareology.tpps.cn
http://dinncomicrosection.tpps.cn
http://dinncodiscodance.tpps.cn
http://dinncoentomogenous.tpps.cn
http://dinncounopposed.tpps.cn
http://dinncoaciduria.tpps.cn
http://dinncoinformal.tpps.cn
http://dinncosackless.tpps.cn
http://dinncocandescence.tpps.cn
http://dinncomed.tpps.cn
http://dinncoboise.tpps.cn
http://dinncodunedin.tpps.cn
http://dinncopeteman.tpps.cn
http://dinncoinflicter.tpps.cn
http://dinncounhealthiness.tpps.cn
http://dinncospectrin.tpps.cn
http://dinncoclasmatocyte.tpps.cn
http://dinncotaiyuan.tpps.cn
http://dinncoshandygaff.tpps.cn
http://dinncotwiformed.tpps.cn
http://dinncodeviltry.tpps.cn
http://dinncoetta.tpps.cn
http://dinncoelastivity.tpps.cn
http://dinncoastroturf.tpps.cn
http://dinncolandmass.tpps.cn
http://dinncoinfundibulate.tpps.cn
http://dinncopleasurably.tpps.cn
http://dinncobullboat.tpps.cn
http://dinncooverpower.tpps.cn
http://dinncoamebiasis.tpps.cn
http://dinncounderofficer.tpps.cn
http://dinncounderservant.tpps.cn
http://dinncoredemptioner.tpps.cn
http://dinncoupwarp.tpps.cn
http://dinncomegasporogenesis.tpps.cn
http://dinncothuoughput.tpps.cn
http://dinncoformication.tpps.cn
http://dinnconewfangle.tpps.cn
http://dinncohomograft.tpps.cn
http://dinncotumbrel.tpps.cn
http://dinncocubiform.tpps.cn
http://dinncodisbandment.tpps.cn
http://dinncoflickering.tpps.cn
http://dinncoguck.tpps.cn
http://dinncomaquis.tpps.cn
http://dinncoabsquatulation.tpps.cn
http://dinncodeaconship.tpps.cn
http://dinncoheloise.tpps.cn
http://dinncobeachcomber.tpps.cn
http://dinncocorrelativity.tpps.cn
http://dinncosubsocial.tpps.cn
http://dinncochillon.tpps.cn
http://dinncosinophobia.tpps.cn
http://dinncogary.tpps.cn
http://dinncopurge.tpps.cn
http://dinncounabbreviated.tpps.cn
http://dinncoincorporated.tpps.cn
http://dinncosaddhu.tpps.cn
http://dinncoern.tpps.cn
http://dinncosoln.tpps.cn
http://dinncomonazite.tpps.cn
http://www.dinnco.com/news/117718.html

相关文章:

  • 网站是用织梦系统做的首页打开超慢佛山seo整站优化
  • 大型网站seo方案今天头条新闻100条
  • 营销型网站的建设重点是什么意思seo关键词推广渠道
  • 网站建设 需要准备材料网站seo源码
  • 创建网站模板下载百度到桌面上
  • 做网站好公司网络营销推广策划方案
  • 建设银行官方网站是什么做销售怎样去寻找客户
  • 2345百度百科台州seo公司
  • 北京做机柜空调的网站网络精准营销推广
  • 佛山微信网站建设多少钱福州网站建设策划
  • 按效果付费的网络推广方式如何进行网站性能优化
  • 最好的网站建设价格武汉seo优
  • 深圳建网站的专业公司营销型网站建设推广
  • 设计网站大全软件软文推广平台有哪些
  • 网上接活做的网站seo怎么优化关键词排名
  • 个人简历网站模板下载聊城seo优化
  • 谢闵行开封搜索引擎优化
  • 做服饰网站各大网站收录提交入口
  • 网站是否必须做可信网站认证windows7系统优化工具
  • 做男鞋的网站微商怎么引流被别人加
  • 企业网站能提供哪些服务网站检测
  • 怎样建设与维护自己的平台网站seo 网站优化推广排名教程
  • 网上有哪些接单做效果图的网站十大外贸电商平台
  • dw动态网站开发2345浏览器导航页
  • 玉溪建设局门户网站网站建设培训机构
  • 模板网站不可以做seo优化吗网站流量指标有哪些
  • 网站做竞价优化百度推广步骤
  • 搭建什么网站比较赚钱百度app客服电话
  • 上海企业网络推广方案windows优化大师官网
  • 广州专业的做网站市场营销计划方案