driver.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <errno.h>
  5. #include <pthread.h>
  6. #include <sys/prctl.h>
  7. #include "auth.h"
  8. #include "driver.h"
  9. #include "protocol.h"
  10. #include "udf_crc.h"
  11. #include "uinputux.h"
  12. /**************************************************
  13. * *
  14. * This file contents functions, which provide *
  15. * interact with fingerprint scanner. *
  16. * *
  17. **************************************************/
  18. /*********************
  19. * UTILS *
  20. *********************/
  21. static void printHex( const unsigned char* data, int length ){
  22. int i = 0;
  23. int k = 0;
  24. for( i = 0; i < length; i++ ){
  25. printf( "0x%02x ", data[i] );
  26. if( k == 7 ) printf( " ");
  27. else if( k == 15 ){
  28. printf( "\n" );
  29. k = 0;
  30. continue;
  31. }
  32. k++;
  33. }
  34. if( k ) printf( "\n" );
  35. }
  36. static void printReceivedPacket( struct driverInstance* this ){
  37. printf( "******************************* PACKET DUMP *******************************\n" );
  38. printf( " Request counter: 0x%02x, packet type 0x%02x, message body length: %i, data:\n",
  39. (this->requestCounter & 0x0f), this->rcvPacketType, this->rcvPacketMessageLength );
  40. printHex( this->packetMessage, this->rcvPacketMessageLength );
  41. printf( "******************************* DUMP END *******************************\n" );
  42. }
  43. static inline unsigned char bindataCompare( const unsigned char* data1, const unsigned char* data2, int length ){
  44. for( int i = 0; i < length; i++ ) if( data1[i] != data2[i] )return 1;
  45. return 0;
  46. }
  47. /*********************
  48. * CONTROL *
  49. *********************/
  50. static inline int deviceControlRead( struct driverInstance* this ){
  51. int res = libusb_control_transfer( this->deviceHandle, 0xc0, 4, 0, 0, this->controlStatus, 8, RQ_TIMEOUT );
  52. return res == 8 ? 0 : res;
  53. }
  54. //0x0400 reset and init
  55. //0x0601 wake up
  56. //0x0602 go to idle
  57. static inline int deviceControlWrite( struct driverInstance* this, uint16_t cmd ){
  58. unsigned char zero[1] = { 0x00 };
  59. int res = libusb_control_transfer( this->deviceHandle, 0x40, 12, 0x0100, cmd, zero, 1, RQ_TIMEOUT );
  60. return res == 1 ? 0 : res;
  61. }
  62. /*********************
  63. * PACKET *
  64. *********************/
  65. /************************************************
  66. func packetPrepareAndSend
  67. Send packet to fingerptint scanner
  68. Caller must prepare
  69. sendPacketType
  70. sendPacketMessageLength
  71. packetMessage(optionaly)
  72. input
  73. Pointer to main driver struct
  74. return
  75. negative on error
  76. 0 on success
  77. *************************************************/
  78. static int packetPrepareAndSend( struct driverInstance* this ){
  79. int err;
  80. int needTransfer;
  81. int alreadyTransferred;
  82. int transferred;
  83. int bulkLength;
  84. uint16_t crc;
  85. //prefix
  86. memcpy( this->_packetData, "Ciao", 4 );
  87. //type
  88. this->_packetData[4] = this->sendPacketType;
  89. //<COUNTER> + length MSB
  90. this->_packetData[5] = this->sendPacketType ? 0 : ( this->requestCounter << 4 ) | ( (this->sendPacketMessageLength >> 8) & 0x0f );
  91. //length LSB
  92. this->_packetData[6] = ( this->sendPacketMessageLength & 0xff );
  93. //if( this->packetDataLength ){}
  94. //CRC
  95. crc = udf_crc ( (this->_packetData+4), (this->sendPacketMessageLength+3) );
  96. this->_packetData[ (this->sendPacketMessageLength+7) ] = ( crc & 0xff );
  97. this->_packetData[ (this->sendPacketMessageLength+8) ] = ( crc >> 8 );
  98. needTransfer = this->sendPacketMessageLength + 9;
  99. alreadyTransferred = 0;
  100. do{
  101. bulkLength = needTransfer - alreadyTransferred;
  102. if( bulkLength > 64 ) bulkLength = 64;
  103. err = libusb_bulk_transfer( this->deviceHandle, BULK_EP_OUT, &this->_packetData[alreadyTransferred], bulkLength, &transferred, RQ_TIMEOUT );
  104. if( err ){
  105. printf( "bulk send err: %i\n", err );
  106. return err;
  107. }
  108. if( transferred != bulkLength ){
  109. printf( "bulk send len err\n" );
  110. return -1;
  111. }
  112. alreadyTransferred += transferred;
  113. }while( needTransfer > alreadyTransferred );
  114. return 0;
  115. }
  116. static int packetReceiveAndParse( struct driverInstance* this ){
  117. char stuckDetect;
  118. int err;
  119. int transferred;
  120. int needReceive;
  121. int alreadyReceived;
  122. int bulkLength;
  123. uint16_t crc;
  124. stuckDetect = 0;
  125. l_receiveNext:
  126. err = libusb_bulk_transfer( this->deviceHandle, BULK_EP_IN, this->_packetData, 64, &transferred, RQ_TIMEOUT );
  127. if( err ){
  128. printf( "bulk rcv err1: %i\n", err );
  129. return err;
  130. }
  131. //minimum possible length is 9: ciao(4) + header(3) + crc(2)
  132. if( transferred < 9 ){
  133. printf( "received data too short: %i\n", transferred );
  134. return -1;
  135. }
  136. //prefix check
  137. if( strncmp( "Ciao", (const char*)this->_packetData, 4 ) ){
  138. printf( "Ciao prefix mismatch\n" );
  139. return -2;
  140. }
  141. //parse header
  142. this->rcvPacketType = this->_packetData[4];
  143. this->rcvPacketMessageLength = ( (this->_packetData[5] & 0x0f) << 8 ) | this->_packetData[6] ;
  144. //If the packet size exceeds 64 bytes, then it is split into several reception sessions.
  145. //the code below checks the length and gets the rest of the packet as needed
  146. //9 means prefix ciao(4) + header(3) + crc(2)
  147. if( (this->rcvPacketMessageLength+9) > 64 ){
  148. alreadyReceived = transferred;
  149. needReceive = this->rcvPacketMessageLength + 9;
  150. do{
  151. bulkLength = needReceive - alreadyReceived;
  152. if( bulkLength > 64 ) bulkLength = 64;
  153. if( (alreadyReceived + bulkLength) > BUFLEN_PACKETDATA ){
  154. printf( "ERROR: Receiving packet too big.\n");
  155. return -11;
  156. }
  157. err = libusb_bulk_transfer( this->deviceHandle, BULK_EP_IN, &this->_packetData[alreadyReceived], bulkLength, &transferred, RQ_TIMEOUT );
  158. if( err ){
  159. printf( "bulk rcv err2: %i\n", err );
  160. return err;
  161. }
  162. if( bulkLength != transferred ){
  163. printf( "bulk rcv err: bulk length != received\n" );
  164. return -1;
  165. }
  166. alreadyReceived += transferred;
  167. }while( alreadyReceived < needReceive );
  168. if( alreadyReceived > needReceive ){
  169. printf( "rcv err: alreadyReceived(%i) > needReceive(%i)\n", alreadyReceived, needReceive );
  170. return -3;
  171. }
  172. }
  173. //CRC check
  174. crc = udf_crc( &this->_packetData[4], (this->rcvPacketMessageLength+3) );
  175. if( this->_packetData[ (this->rcvPacketMessageLength+7) ] != ( crc & 0xff )
  176. || this->_packetData[ (this->rcvPacketMessageLength+8) ] != ( crc >> 8 ) ){
  177. printf( "rcv packet err: crc mismatch\n" );
  178. return -4;
  179. }
  180. //answer the type 08
  181. if( this->rcvPacketType == 0x08 && !this->rcvPacketMessageLength ){
  182. if( stuckDetect > 10 ){
  183. //TODO: scanner reset on stuck
  184. printf( "WARNING: Fingerprint scanner seems has been hung up!\n" );
  185. return -5;
  186. }
  187. this->sendPacketType = 0x09;
  188. this->sendPacketMessageLength = 0;
  189. err = packetPrepareAndSend( this );
  190. if( err ){
  191. printf( "rcv packet 08 answer send err: %i\n", err );
  192. return err;
  193. }
  194. stuckDetect++;
  195. goto l_receiveNext;
  196. }
  197. //Check counter if it is not a request from the device
  198. if( !this->rcvPacketType ){
  199. if( ( this->_packetData[5] >> 4 ) == (this->requestCounter & 0x0f) ){
  200. this->requestCounter++;
  201. }else{
  202. printf( "Reseived packet counter mismatch.\n" );
  203. return -66;
  204. }
  205. }
  206. return 0;
  207. }
  208. /**********************
  209. * PROCESSING *
  210. **********************/
  211. static int packetSequenceMapProcessor( struct driverInstance* this, const struct packet_sequence_map* sequence, const char* mapname ){
  212. int err;
  213. printf( "Processing packet sequence map [%s]...\n", mapname );
  214. for( int i = 0; sequence[i].action; i++ ){
  215. if( sequence[i].action & ACTION_READ ){//read packet
  216. err = packetReceiveAndParse( this );
  217. if( err ){
  218. printf( "Receive packet error: %i, sequence: %i\n", err, i );
  219. return err;
  220. }
  221. if( this->rcvPacketType != sequence[i].type ) err |= 1;
  222. if( this->rcvPacketMessageLength != sequence[i].messageLength ) err |= ( 1<< 1 );
  223. if( bindataCompare( this->packetMessage, sequence[i].data, this->rcvPacketMessageLength ) ) err |= ( 1 << 2 );
  224. if( err ){
  225. printf( "\nPacket signature mismatch. flags: [%c%c%c], sequence: %i\n",
  226. err & 1 ? 't' : '.', //type mismatch
  227. err & (1<<1) ? 'l' : '.', //length mismatch
  228. err & (1<<2) ? 'd' : '.', //data mismatch
  229. i
  230. );
  231. printReceivedPacket( this );
  232. if( sequence[i].action & ACT_ERR_IGN ){
  233. printf( "This mismatch ignored\n" );
  234. err = 0;
  235. } else return err;
  236. }
  237. } else {//send packet
  238. this->sendPacketType = sequence[i].type;
  239. this->sendPacketMessageLength = sequence[i].messageLength;
  240. if( this->sendPacketMessageLength ) memcpy( this->packetMessage, sequence[i].data, this->sendPacketMessageLength );
  241. err = packetPrepareAndSend( this );
  242. if( err ){
  243. printf( "Send packet error: %i, sequence: %i\n", err, i );
  244. return err;
  245. }
  246. }
  247. }//for()
  248. printf( "Packet sequence map [%s] processing done(%i).\n", mapname, err );
  249. return 0;
  250. }
  251. /****************************************************************
  252. func commandExecute
  253. send command to scanner using packet type 0
  254. input
  255. this - pointer to driverInstance
  256. cmd - pointer to message data
  257. cmdlen - length of message
  258. action - ACTION_READ if need receive and parse packet, else 0
  259. return
  260. 0 on success
  261. not 0 on error
  262. *****************************************************************/
  263. static int commandExecute( struct driverInstance* this, const unsigned char* cmd, int cmdLen, unsigned char action ){
  264. int err;
  265. this->sendPacketType = 0;
  266. this->sendPacketMessageLength = cmdLen;
  267. memcpy( this->packetMessage, cmd, cmdLen );
  268. err = packetPrepareAndSend( this );
  269. if( err ){
  270. printf( "Failed send command to execute. code %i\n", err );
  271. return err;
  272. }
  273. if( action & ACTION_READ ){
  274. err = packetReceiveAndParse( this );
  275. if( err ){
  276. printf( "Failed receive command execute result. code: %i\n", err );
  277. return err;
  278. }
  279. }
  280. return 0;
  281. }
  282. /**********************
  283. * MESSAGE *
  284. **********************/
  285. static int messageReceiveRestData( struct driverInstance* this ){
  286. int err;
  287. unsigned char confirm[1] = { 0x30 };
  288. do{
  289. err = commandExecute( this, confirm, 1, ACTION_READ );
  290. if( err ){
  291. printf( "(%s) Command execute error: %i\n", __FUNCTION__, err );
  292. return err;
  293. }
  294. if( this->rcvPacketType ||
  295. !this->rcvPacketMessageLength ||
  296. (this->packetMessage[0] != 0x24 && this->packetMessage[0] != 0x20)
  297. ){
  298. printf( "(%s) Wrong packet\n", __FUNCTION__ );
  299. printReceivedPacket( this );
  300. return -EPROTO;
  301. }
  302. if( (this->dataLength + this->rcvPacketMessageLength - 1) > BUFLEN_DATA ){
  303. printf( "Data too big (%i > %i)\n", (this->dataLength + this->rcvPacketMessageLength - 1), BUFLEN_DATA );
  304. return -EMSGSIZE;
  305. }
  306. memcpy( &this->data[this->dataLength], &this->packetMessage[1], (this->rcvPacketMessageLength - 1) );
  307. this->dataLength += this->rcvPacketMessageLength -1;
  308. }while( this->packetMessage[0] == 0x24 );
  309. return 0;
  310. }
  311. /**************************
  312. * FLASH MEMORY ACCESS *
  313. **************************/
  314. static int flashWriteRegion( struct driverInstance* this, unsigned char region ){
  315. int err;
  316. int dataRemain;
  317. int dataSending;
  318. int dataSent;
  319. //write request template flag lsb msb reg lsb msb
  320. unsigned char request[15] = { 0x28, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0xfc, 0x58, 0xc4, 0x63, 0x00, 0x00, 0x00, 0x00 };
  321. const unsigned char response[7] = { 0x28, 0x04, 0x00, 0x00, 0x00, 0x01, 0x14 };
  322. if( region != 0xfb && region != 0xfc ){
  323. printf( "!!!ATTEMPT TO WRITE WRONG MEMORY REGION 0x%02x!!!\n", region );
  324. return -EINVAL;
  325. }
  326. dataSent = 0;
  327. dataRemain = this->dataLength;
  328. //message and command header
  329. request[12] = ( this->dataLength >> 8 ) & 0xff;//msb
  330. request[11] = this->dataLength & 0xff;//lsb
  331. request[7] = region;
  332. request[2] = ( (this->dataLength+12) >> 8 ) & 0xff;//msb
  333. request[1] = (this->dataLength+12) & 0xff;//lsb
  334. //decide size of sending data
  335. if( dataRemain > 2028 ){
  336. request[0] = 0x2c;
  337. dataSending = 2028;//2043 - 15
  338. } else {
  339. request[0] = 0x28;
  340. dataSending = this->dataLength;
  341. }
  342. //copy data
  343. this->sendPacketMessageLength = dataSending + 15;
  344. memcpy( this->packetMessage, request, 15 );
  345. if( dataSending ) memcpy( &this->packetMessage[15], this->data, dataSending );
  346. l_sendData:
  347. dataRemain -= dataSending;
  348. this->sendPacketType = 0x00;
  349. err = packetPrepareAndSend( this );
  350. if( !err ) err = packetReceiveAndParse( this );
  351. if( err ){
  352. printf( "Memory write error: %i\n", err );
  353. return err;
  354. }
  355. //if all data sent
  356. if( !dataRemain ){
  357. //check the answer
  358. if( this->rcvPacketType || this->rcvPacketMessageLength != 7 || bindataCompare(this->packetMessage, response, 7) ){
  359. printf( "Memory write error: all data sent, but get wrong packet\n" );
  360. printReceivedPacket( this );
  361. return -EPROTO;
  362. }
  363. return 0;
  364. }
  365. //if there is data left to send
  366. if( this->rcvPacketType || this->rcvPacketMessageLength != 1 || this->packetMessage[0] != 0x30 ){
  367. printf( "Memory write error: data left, but get wrong packet\n" );
  368. printReceivedPacket( this );
  369. return -EPROTO;
  370. }
  371. dataSent += dataSending;
  372. //decide size of sending data
  373. if( dataRemain > 2042 ){
  374. this->packetMessage[0] = 0x24;
  375. dataSending = 2042;
  376. } else {
  377. this->packetMessage[0] = 0x20;
  378. dataSending = dataRemain;
  379. }
  380. //copy next data
  381. this->sendPacketMessageLength = dataSending + 1;
  382. memcpy( &this->packetMessage[1], &this->data[dataSent], dataSending );
  383. goto l_sendData;
  384. }
  385. static int flashReadRegion( struct driverInstance* this, unsigned char region ){
  386. int err;
  387. int dataLength;
  388. //request template 0xfc
  389. unsigned char request[11] = { 0x28, 0x08, 0x00, 0x00, 0x00, 0x02, 0x04, 0xfb, 0x58, 0xc4, 0x63 };
  390. if( region != 0xfb && region != 0xfc ){
  391. printf( "!!!ATTEMPT TO READ WRONG MEMORY REGION: 0x%02X!!!\n", region );
  392. return -EINVAL;
  393. }
  394. this->dataLength = 0;
  395. request[7] = region;
  396. err = commandExecute( this, request, 11, ACTION_READ );
  397. if( err ){
  398. printf( "Error executing command to read memory: %i\n", err );
  399. return err;
  400. }
  401. if( this->rcvPacketType != 0 ||
  402. this->rcvPacketMessageLength < 7 ||
  403. bindataCompare(&this->packetMessage[3], &request[3], 3) ||
  404. this->packetMessage[6] != 0x14
  405. ){
  406. printf( "Error reading memory: wrong packet.\n");
  407. printReceivedPacket( this );
  408. return -EPROTO;
  409. }
  410. dataLength = this->packetMessage[7] | (this->packetMessage[8] << 8);
  411. memcpy( this->data, &this->packetMessage[11], (this->rcvPacketMessageLength - 11) );
  412. this->dataLength = this->rcvPacketMessageLength - 11;
  413. if( this->packetMessage[0] == 0x2c ){
  414. err = messageReceiveRestData( this );
  415. if( err ){
  416. printf( "Memory read error: messageReceiveRestData failed: %i\n", err );
  417. return err;
  418. }
  419. }
  420. if( this->dataLength != dataLength ){
  421. printf( "ERROR: memory read length mismatch %i != %i.\n", dataLength, this->dataLength );
  422. return -EPROTO;
  423. }
  424. return 0;
  425. }
  426. /*********************
  427. * RAM *
  428. *********************/
  429. static int ramWrite( struct driverInstance* this, unsigned char flag ){
  430. int err;
  431. //set flag
  432. this->ramData[94] = flag;
  433. //prepare data
  434. this->sendPacketType = 0x00;
  435. this->sendPacketMessageLength = 111;
  436. memcpy( this->packetMessage, ramWriteRequest, 15 );
  437. memcpy( &this->packetMessage[15], this->ramData, BUFLEN_RAMDATA );
  438. //send data
  439. err = packetPrepareAndSend( this );
  440. if( !err ) err = packetReceiveAndParse( this );
  441. if( err ){
  442. printf( "Ram write error: %i\n", err );
  443. return err;
  444. }
  445. if( this->rcvPacketMessageLength != 7 || bindataCompare(ramWriteResponse, this->packetMessage, 7) ){
  446. printf( "Ram write error: got unexpeced packet.\n" );
  447. printReceivedPacket( this );
  448. return -EPROTO;
  449. }
  450. return err;
  451. }
  452. static int ramRead( struct driverInstance* this ){
  453. int err;
  454. err = commandExecute( this, ramReadRequest, 11, ACTION_READ );
  455. if( err ){
  456. printf( "Ram read: command execution error: %i\n", err );
  457. return err;
  458. }
  459. if( this->rcvPacketMessageLength != 107 || bindataCompare(ramReadResponse, this->packetMessage, 11) ){
  460. printf( "Ram read error: got unexpecet packet.\n" );
  461. printReceivedPacket( this );
  462. return -EPROTO;
  463. }
  464. memcpy( this->ramData, &this->packetMessage[11], BUFLEN_RAMDATA );
  465. return 0;
  466. }
  467. /*********************
  468. * OPERATIONS *
  469. *********************/
  470. static int deviceInit( struct driverInstance* this ){
  471. int err;
  472. //write control to init and check it
  473. err = deviceControlWrite( this, CONTROL_INIT );
  474. if( !err ) err = deviceControlRead( this );
  475. if( !err ) err = bindataCompare( &this->controlStatus[4], state_40_a8_00_30, 4 );
  476. printf( "[init] Control %s.\n", err ? "error" : "success" );
  477. if( err ) return err;
  478. //command sequence to init device
  479. err = packetSequenceMapProcessor( this, init_map, "device init" );
  480. if( err ) return err;
  481. //ram config
  482. err = ramRead( this );
  483. if( !err ) err = ramWrite( this, RAMFLAG_DEFAULT );
  484. printf( "[init] Ram config %s.\n", err ? "error" : "success" );
  485. return err;
  486. }
  487. static int touchpadMode( struct driverInstance* this ){
  488. int err;
  489. int ufd;//uinput file descriptor
  490. void ( *uinputEventHandler )( int, short* );
  491. //select uinput event handler
  492. if( this->touchpadMode == MODE_TOUCHPAD_MOUSE ) uinputEventHandler = uinputEventMouse;
  493. else if( this->touchpadMode == MODE_TOUCHPAD_WHEELS ) uinputEventHandler = uinputEventWheels;
  494. else if( this->touchpadMode == MODE_TOUCHPAD_ARROWS ) uinputEventHandler = uinputEventArrows;
  495. else{
  496. printf( "[touchpad] unknown touchpad mode: 0x%02x\n", this->touchpadMode );
  497. return -EINVAL;
  498. }
  499. //open uinput device
  500. ufd = uinputOpen();
  501. if( ufd < 0 ){
  502. printf( "[touchpad] WARNING: Cannot open uinput.\n" );
  503. printf( "[touchpad] Going into idle mode.\n" );
  504. this->modeSwitcher = MODE_IDLE;
  505. return 0;
  506. }
  507. //switch scanner into touchpad mode
  508. err = commandExecute( this, touchpad_mode_request, 11, 0 );
  509. l_receiveNextPacket:
  510. if( !err ) err = packetReceiveAndParse( this );
  511. if( err ){
  512. printf( "[touchpad] Communicate error: %i\n", err );
  513. goto l_modeExit;
  514. }
  515. //if touchpad protocol packet
  516. if( this->rcvPacketType == 0x0b && this->rcvPacketMessageLength == 6 ) {
  517. uinputEventHandler( ufd, (short*)this->packetMessage );
  518. this->sendPacketType = 0x0b;
  519. this->sendPacketMessageLength = 1;
  520. this->packetMessage[0] = 0x01;
  521. //change mode or uinput event handler
  522. if( this->modeSwitcher != MODE_TOUCHPAD ){
  523. if( this->modeSwitcher == MODE_TOUCHPAD_MOUSE ) uinputEventHandler = uinputEventMouse;
  524. else if( this->modeSwitcher == MODE_TOUCHPAD_WHEELS ) uinputEventHandler = uinputEventWheels;
  525. else if( this->modeSwitcher == MODE_TOUCHPAD_ARROWS ) uinputEventHandler = uinputEventArrows;
  526. else{
  527. this->packetMessage[0] = 0x00;//set continue flag to false for exit touchpad mode
  528. goto l_sendNextPacket;
  529. }
  530. this->touchpadMode = this->modeSwitcher;
  531. this->modeSwitcher = MODE_TOUCHPAD;
  532. sem_post( &this->semaphoreIpc );//notify ipcd about touchpad mode change
  533. }
  534. l_sendNextPacket:
  535. err = packetPrepareAndSend( this );
  536. goto l_receiveNextPacket;
  537. }
  538. //if not touchpad response, then protocol error
  539. if( this->rcvPacketMessageLength != 7 || bindataCompare(touchpad_mode_response, this->packetMessage, 7) ) {
  540. printf( "[touchpad] Received wrong packet\n" );
  541. printReceivedPacket( this );
  542. err = -EPROTO;
  543. goto l_modeExit;
  544. }
  545. err = 0;
  546. sem_post( &this->semaphoreIpc );//notify ipcd about mode exit
  547. l_modeExit:
  548. uinputClose( ufd );
  549. return err;
  550. }
  551. /*
  552. //I don't know what's going on here. The Windows driver does
  553. //this after capturing an image from the scanner, but not always.
  554. static int uncnownAction1( struct driverInstance* this ){
  555. int err;
  556. err = commandExecute( this, unknown_action1_request, 15, ACTION_READ );
  557. if( err ){
  558. printf( "UA1) request error: %i\n", err );
  559. return err;
  560. }
  561. if( !bindataCompare( unknown_action1_success, this->packetMessage, 7 ) && this->rcvPacketMessageLength == 7 ) printf( "UA1) success\n" );
  562. else if( !bindataCompare( unknown_action1_failure, this->packetMessage, 7 ) && this->rcvPacketMessageLength == 7 ) printf( "UA1) fail\n" );
  563. else{
  564. printf( "UA1) received unknown packet\n" );
  565. printReceivedPacket( this );
  566. return -EPROTO;
  567. }
  568. return 0;
  569. }
  570. */
  571. //I think it has something to do with image quality. When I very quickly run
  572. //my finger over the scanner, values below 100% often appear here.
  573. static int requestPictureQuality( struct driverInstance* this ){
  574. int err;
  575. err = commandExecute( this, image_quality_request, 7, ACTION_READ );
  576. if( err ){
  577. printf( "Image quality request error: %i\n", err );
  578. return err;
  579. }
  580. if(
  581. this->rcvPacketMessageLength == 11 &&
  582. !bindataCompare( image_quality_responce, this->packetMessage, 7 ) &&
  583. !bindataCompare( &image_quality_responce[8], &this->packetMessage[8], 3 )
  584. ){
  585. //0x28 0x08 0x00 0x00 0x00 0x15 0x12 0x00 0x00 0x00 0x00
  586. // ----
  587. // this byte
  588. this->scanQuality = this->packetMessage[7];
  589. return 0;
  590. }
  591. printf( "wrong [image quality] paket\n" );
  592. printReceivedPacket( this );
  593. return -EPROTO;
  594. }
  595. /*
  596. static void pictureSaveFile( struct driverInstance* this ){
  597. FILE* imgFile;
  598. imgFile = fopen( "fimg", "w" );
  599. if( imgFile ){
  600. fwrite( "P5 144 270 255\n", 1, 15, imgFile );
  601. fwrite( this->data, 1, this->dataLength, imgFile );
  602. fclose( imgFile );
  603. }
  604. }
  605. */
  606. /**************
  607. scanResuilt
  608. 0 - all ok
  609. -EIO - on driver error
  610. -ETIMEDOUT - on scanning timeout
  611. -ECANCELED - on cancel scanning
  612. 0x07 - User slid their finger too far to the left
  613. 0x08 - User slid their finger too far to the right
  614. 0x0b - The quality of the fingerprint is poor
  615. 0x0f - User swiped the scanner incorrectly
  616. 0x1c - User swiped the scanner too quickly
  617. 0x1d - The finger slid strongly horizontally
  618. 0x1e - User swiped the scanner too short
  619. **************/
  620. static int fingerScanPolling( struct driverInstance* this ){
  621. int err;
  622. unsigned char scan_request[14] = { 0x28, 0x0b, 0x00, 0x00, 0x00, 0x0e, 0x02, 0xc0, 0xd4, 0x01, 0x00, 0x02, 0x01, 0x00 };
  623. unsigned char scan_poll[8] = { 0x28, 0x05, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01 };// ----
  624. // ----
  625. l_scanAgain:
  626. scan_poll[7] = 0x01;//cancel flag
  627. //scan_request[12] = 0x01;//fail detection
  628. err = commandExecute( this, scan_request, 14, ACTION_READ );
  629. l_poll:
  630. if( err ){
  631. printf( "[scan] finger scan request err: %i\n", err );
  632. goto l_error;
  633. }
  634. //poll response
  635. if( this->rcvPacketMessageLength == 20 &&
  636. !bindataCompare( this->packetMessage, _finger_scan_poll_response, 11 ) &&
  637. !bindataCompare( &this->packetMessage[12], &_finger_scan_poll_response[12], 8 )
  638. ){
  639. switch( this->packetMessage[11] ){
  640. case 0x00: //get ready, next response will be with picture
  641. case 0x0c: //not ready
  642. break;
  643. case 0x07: //Finger shifted to the left
  644. case 0x08: //Finger shifted to the right
  645. case 0x0b: //Bad quality
  646. case 0x0f: //Wrong swipe
  647. case 0x1c: //Swiped too fast
  648. case 0x1d: //Finger shifted
  649. case 0x1e: //Swiped too short
  650. this->scanResult = this->packetMessage[11];
  651. this->driverState = STATE_WAIT_IPC;
  652. sem_post( &this->semaphoreIpc );
  653. sem_wait( &this->semaphoreScan );
  654. this->driverState = STATE_RUNNING;
  655. break;
  656. default:
  657. printf( "[scan] Warning: unknown poll code 0x%02x\n", this->packetMessage[11] );
  658. }
  659. if( this->modeSwitcher != MODE_SCANNING ) scan_poll[7] = 0x00;
  660. err = commandExecute( this, scan_poll, 8, ACTION_READ );
  661. goto l_poll;
  662. }
  663. if( this->rcvPacketMessageLength == 7 ){
  664. if( !bindataCompare(this->packetMessage, finger_scan_response_canceled, 7) ){
  665. this->scanResult = -ECANCELED;
  666. goto l_scanFinish;
  667. }
  668. if( !bindataCompare(this->packetMessage, finger_scan_response_timeout, 7) ){
  669. this->scanResult = -ETIMEDOUT;
  670. goto l_scanFinish;
  671. }
  672. }
  673. //answer with picture?
  674. if( this->rcvPacketMessageLength == 2043 && !bindataCompare(this->packetMessage, finger_scan_response_picture, 11) ){
  675. //2043 - 11 = 2032
  676. memcpy( this->data, &this->packetMessage[11], 2032 );
  677. this->dataLength = 2032;
  678. err = messageReceiveRestData( this );
  679. if( !err ) err = requestPictureQuality( this );
  680. if( err ){
  681. printf( "[scan] picture receive or quality request error: %i\n", err );
  682. goto l_error;
  683. }
  684. if( this->dataLength != 38880 ){
  685. printf( "[scan] Error: Unexpected image size: %i.\n", this->dataLength );
  686. err = -EPROTO;
  687. goto l_error;
  688. }
  689. printf( "[scan] Received image quality %i%%\n", this->scanQuality );
  690. this->scanResult = 0;
  691. goto l_scanFinish;
  692. }
  693. printf( "[scan] Unknown packet received:\n" );
  694. printReceivedPacket( this );
  695. err = -EPROTO; //unknown packet
  696. l_error:
  697. this->scanResult = -EIO;
  698. this->driverState = STATE_WAIT_IPC;
  699. sem_post( &this->semaphoreIpc );
  700. sem_wait( &this->semaphoreScan );
  701. this->driverState = STATE_RUNNING;
  702. return err;
  703. l_scanFinish:
  704. this->driverState = STATE_WAIT_IPC;
  705. sem_post( &this->semaphoreIpc );
  706. sem_wait( &this->semaphoreScan );
  707. this->driverState = STATE_RUNNING;
  708. if( this->modeSwitcher == MODE_SCANNING ){
  709. printf( "[scan] Scanning again\n" );
  710. goto l_scanAgain;
  711. }
  712. return 0;
  713. }
  714. static int idlingMode( struct driverInstance* this ){
  715. int err;
  716. struct timespec timeToWaitSemaphore;
  717. l_go_to_idle:
  718. //send command to idle
  719. err = commandExecute( this, cmd_to_idle, 14, 0 );
  720. if( err ){
  721. printf( "[idle] command to idle error: %i\n", err );
  722. return err;
  723. }
  724. //set control to idle
  725. err = deviceControlWrite( this, CONTROL_TO_IDLE );
  726. if( err ){
  727. printf( "[idle] control to idle error: %i\n", err );
  728. return err;
  729. }
  730. //request interrupt and wait semaphore
  731. if( this->interruptStatus ) sem_post( &this->semaphoreInterrupt );
  732. l_waitSemaphore:
  733. sem_wait( &this->semaphoreIdle );
  734. //passive auth mode switch
  735. if( this->passiveAuthModeSwitcher != this->passiveAuthModeIndicator ){
  736. this->passiveAuthModeIndicator = this->passiveAuthModeSwitcher;
  737. this->driverState = STATE_WAIT_IPC;
  738. sem_post( &this->semaphoreIpc );
  739. sem_wait( &this->semaphoreScan );
  740. this->driverState = STATE_RUNNING;
  741. goto l_waitSemaphore;
  742. }
  743. //check error in interrupt thread
  744. if( this->interruptStatus < 0 ){
  745. printf( "[idle] interrupt thread return error: %i\n", this->interruptStatus );
  746. return this->interruptStatus;
  747. }
  748. //set control to wake up
  749. err = deviceControlWrite( this, CONTROL_WAKE_UP );
  750. if( err ){
  751. printf( "[idle] device control wake up error: %i\n", err );
  752. return err;
  753. }
  754. //read "to idle" comand response
  755. err = packetReceiveAndParse( this );
  756. if( err ){
  757. printf( "[idle] read 'to idle' command response error: %i\n", err );
  758. return err;
  759. }
  760. //check received packet type
  761. if( this->rcvPacketType ){
  762. printf( "[idle] received unexpected packet:\n" );
  763. printReceivedPacket( this );
  764. return -EPROTO;
  765. }
  766. //maybe this is failed finger scan?
  767. if( this->rcvPacketMessageLength == 7 ){
  768. //This occurs when poorly or accidentally touching the fingerprint scanner.
  769. if( !bindataCompare(this->packetMessage, idle_answer_error1, 7) ) goto l_go_to_idle;
  770. if( !bindataCompare(this->packetMessage, idle_answer_error2, 7) ) goto l_go_to_idle;
  771. }
  772. //maybe this is fingerprint image?
  773. if( this->rcvPacketMessageLength == 2043 && !bindataCompare(this->packetMessage, idle_answer_picture, 19) ){
  774. memcpy( this->data, &this->packetMessage[19], (this->rcvPacketMessageLength - 19) );
  775. this->dataLength = this->rcvPacketMessageLength - 19;
  776. err = messageReceiveRestData( this );
  777. if( err ){
  778. printf( "[idle] receive picture error: %i\n", err );
  779. return err;
  780. }
  781. if( this->dataLength != 38880 ){
  782. printf( "[idle] Error: Unexpected image size: %i.\n", this->dataLength );
  783. return -EPROTO;
  784. }
  785. err = requestPictureQuality( this );
  786. if( err ){
  787. printf( "[idle] PictureQuality request error: %i\n", err );
  788. return err;
  789. }
  790. printf( "[idle] Received image quality %i%%\n", this->scanQuality );
  791. authFingerTrigger( this );
  792. //pictureSaveFile( this );
  793. goto l_go_to_idle;
  794. }
  795. //if this is not a correct awakening, then something is wrong
  796. if( this->rcvPacketMessageLength != 15 || bindataCompare(this->packetMessage, idle_answer, 15) ){
  797. printf( "[idle] received unexpected packet:\n" );
  798. printReceivedPacket( this );
  799. return -EPROTO;
  800. }
  801. //if current mode is idle, then go to idle
  802. if( this->modeSwitcher == MODE_IDLE ){
  803. printf( "[idle] WARNING: Wake up without action.\n" );
  804. printf( "[idle] Last data in control status: " );
  805. printHex( this->controlStatus, 4 );
  806. printf( "[idle] Going to idle.\n" );
  807. goto l_go_to_idle;
  808. }
  809. //get current time and add 5 sec
  810. err = clock_gettime( CLOCK_REALTIME, &timeToWaitSemaphore );
  811. if( err ){
  812. perror( "[idle] clock" );
  813. return err;
  814. }
  815. timeToWaitSemaphore.tv_sec += 5;
  816. //waiting for an interruption that come in the process of awakening
  817. err = sem_timedwait( &this->semaphoreIdle, &timeToWaitSemaphore );
  818. if( err && errno == ETIMEDOUT ){
  819. printf( "[idle] WARNING: After wake up interrupt not got.\n" );
  820. printf( "[idle] Last data in control register: ");
  821. printHex( this->controlStatus, 4 );
  822. }
  823. sem_post( &this->semaphoreIpc ); //notifi ipcd about mode exiting
  824. return 0;
  825. }
  826. /****************************
  827. * INTERRUPT HANDLER *
  828. ****************************/
  829. //this function works in a separate thread
  830. static void* deviceInterruptHandler( void* arg ){
  831. struct driverInstance* this = arg;
  832. int err;
  833. int transferred;
  834. prctl( PR_SET_NAME, "IRQ", 0, 0, 0 );
  835. l_waitSemaphore:
  836. this->interruptStatus = 1;
  837. sem_wait( &this->semaphoreInterrupt );
  838. this->interruptStatus = 0;
  839. l_waitInterrupt:
  840. err = libusb_interrupt_transfer( this->deviceHandle, INT_EP_IN, this->controlStatus, 4, &transferred, 0 );
  841. if( err ){
  842. printf( "[interrupt] ERROR: Transfer return code %i\n", err );
  843. this->interruptStatus = err;
  844. goto l_error;
  845. }
  846. if( transferred != 4 ){
  847. printf( "[interrupt] ERROR: Transferred != 4\n" );
  848. this->interruptStatus = -1;
  849. goto l_error;
  850. }
  851. //ignore these interrupts
  852. if( !bindataCompare(this->controlStatus, state_00_80_00_30, 4) ) goto l_waitInterrupt;
  853. if( !bindataCompare(this->controlStatus, state_00_80_02_30, 4) ) goto l_waitInterrupt;
  854. if( !bindataCompare(this->controlStatus, state_00_80_03_30, 4) ) goto l_waitInterrupt;
  855. if( !bindataCompare(this->controlStatus, state_00_c0_03_30, 4) ) goto l_waitInterrupt;
  856. if( !bindataCompare(this->controlStatus, state_38_b0_00_30, 4) ) goto l_waitInterrupt;
  857. //these interrupts come in the process of awakening
  858. if( !bindataCompare(this->controlStatus, state_40_a8_00_30, 4) ) goto l_sem_post;
  859. if( !bindataCompare(this->controlStatus, state_40_b0_00_30, 4) ) goto l_sem_post;
  860. //user touch fingerprint scanner
  861. if( !bindataCompare(this->controlStatus, state_40_a8_02_30, 4) ) goto l_sem_post;
  862. printf( "[interrupt] WARNING: Unknown state: " );
  863. printHex( this->controlStatus, 4 );
  864. l_sem_post:
  865. sem_post( &this->semaphoreIdle );
  866. goto l_waitSemaphore;
  867. l_error:
  868. sem_post( &this->semaphoreIdle );
  869. return NULL;
  870. }
  871. /***************************************************************
  872. semaphoreIpc up rules
  873. notification about entering mode sends by driverModeSwitcher
  874. notification about exiting mode sends by a mode handler
  875. ***************************************************************/
  876. static int driverModeSwitcher( struct driverInstance* this ){
  877. int err;
  878. //just in case
  879. this->modeIndicator = MODE_IDLE;
  880. this->modeSwitcher = MODE_IDLE;
  881. //do not semaphoreIpc up on driver starts
  882. goto l_startIdle;
  883. l_switchMode:
  884. if( this->modeSwitcher == MODE_IDLE ){
  885. this->modeIndicator = MODE_IDLE;
  886. sem_post( &this->semaphoreIpc );//notify ipc about mode change
  887. l_startIdle:
  888. printf( "[switch] Entering into idle mode...\n" );
  889. err = idlingMode( this );
  890. if( err ){
  891. printf( "[switch] Idling mode exited with code: %i\n", err );
  892. return err;
  893. }
  894. goto l_switchMode;
  895. }
  896. if( this->modeSwitcher == MODE_TOUCHPAD ){
  897. this->modeIndicator = MODE_TOUCHPAD;
  898. printf( "[switch] Entering into touchpad mode...\n" );
  899. sem_post( &this->semaphoreIpc );//notify ipc about mode change
  900. err = touchpadMode( this );
  901. if( err ){
  902. printf( "[switch] touchpadMode returns error: %i\n", err );
  903. return err;
  904. }
  905. goto l_switchMode;
  906. }
  907. if( this->modeSwitcher == MODE_SCANNING ){
  908. this->modeIndicator = MODE_SCANNING;
  909. err = ramWrite( this, RAMFLAG_SCAN );
  910. if( !err ){
  911. printf( "[switch] Entering into scanning mode...\n" );
  912. sem_post( &this->semaphoreIpc );//notify ipc about mode change
  913. err = fingerScanPolling( this );
  914. }
  915. if( !err ) err = ramWrite( this, RAMFLAG_DEFAULT );
  916. if( err ){
  917. printf( "[switch] fingerScanPolling error: %i\n", err );
  918. return err;
  919. }
  920. goto l_switchMode;
  921. }
  922. printf( "[switch] WARNING! Unknown mode switch 0x%02x.\n", this->modeSwitcher );
  923. return -EINVAL;
  924. }
  925. /********************
  926. * ENTRY *
  927. ********************/
  928. void* ipcdEntryPoint( void* arg );
  929. int daemonEntryPoint( libusb_device_handle* deviceHandle, int launcherdSocket ){
  930. int err;
  931. pthread_t threadIpcd;
  932. pthread_t threadInterrupt;
  933. struct driverInstance this;
  934. //init some struct fields
  935. this.deviceHandle = deviceHandle;
  936. this.launcherdSocket = launcherdSocket;
  937. this.packetMessage = &this._packetData[7];
  938. this.requestCounter = 0x00;
  939. this.interruptStatus = 1;
  940. this.modeIndicator = MODE_IDLE;
  941. this.modeSwitcher = MODE_IDLE;
  942. this.driverState = STATE_RUNNING;
  943. this.passiveAuthUsername = NULL;
  944. this.passiveAuthModeSwitcher = PA_STOP;
  945. this.passiveAuthModeIndicator = PA_STOP;
  946. sem_init( &this.semaphoreIpc, 0, 0 );
  947. sem_init( &this.semaphoreIdle, 0, 0 );
  948. sem_init( &this.semaphoreScan, 0, 0 );
  949. sem_init( &this.semaphoreInterrupt, 0, 0 );
  950. err = deviceInit( &this );//init device
  951. if( !err ) err = pthread_create( &threadInterrupt, NULL, deviceInterruptHandler, &this );
  952. if( !err ) err = pthread_create( &threadIpcd, NULL, ipcdEntryPoint, &this );
  953. if( !err ) err = driverModeSwitcher( &this );//go to main loop
  954. //
  955. //
  956. //TODO: correct threads stop
  957. //
  958. //
  959. //cleanup
  960. sem_destroy( &this.semaphoreIpc );
  961. sem_destroy( &this.semaphoreIdle );
  962. sem_destroy( &this.semaphoreScan );
  963. sem_destroy( &this.semaphoreInterrupt );
  964. return err;
  965. }
  966. //do not notice about unused functions
  967. void shutUp( void ){
  968. flashReadRegion( NULL, 0 );
  969. flashWriteRegion( NULL, 0 );
  970. }