To avoid any misunderstanding, here is the complete code for a new keymouse.c that implements the absolute position report map I posted earlier. It uses the keymouse.txt file currently on the github site, and overrides its SIZE settings by specifying the new packet lengths in write_ctic(). As an illustration it moves the cursor around a rectangle at the top left of the screen once per second. It works fine with a Windows PC.
Code:
/******** KEYMOUSE.C *********COMPILE gcc keymouse.c btlib.c -o keymouse RUN sudo ./keymouse********************************/#include <stdio.h>#include <stdlib.h>#include "btlib.h" int lecallback(int clientnode,int op,int cticn);int send_key(int key);int send_mouse(int x,int y);unsigned char reportmap[100] = {0x05,0x01,0x09,0x06,0xA1,0x01,0x85,0x01,0x05,0x07,0x19,0xE0,0x29,0xE7,0x15,0x00, 0x25,0x01,0x75,0x01,0x95,0x08,0x81,0x02,0x95,0x01,0x75,0x08,0x81,0x01,0x95,0x06, 0x75,0x08,0x15,0x00,0x25,0x65,0x05,0x07,0x19,0x00,0x29,0x65,0x81,0x00,0xC0, 0x05,0x01,0x09,0x02,0xA1,0x01,0x85,0x02,0x09,0x01,0xA1,0x00,0x05,0x09,0x19,0x01, 0x29,0x03,0x15,0x00,0x25,0x01,0x95,0x03,0x75,0x01,0x81,0x02,0x95,0x01,0x75,0x05, 0x81,0x03,0x05,0x01,0x09,0x30,0x09,0x31,0x15,0x01,0x26,0xFF,0x75,0x75,0x10,0x95,0x02, 0x81,0x02,0xC0,0xC0};unsigned char report[8] = {0,0,0,0,0,0,0,0};unsigned char *name = "HID"; unsigned char appear[2] = {0xC1,0x03}; // 03C1 = keyboard icon appears on connecting device unsigned char pnpinfo[7] = {0x02,0x6B,0x1D,0x46,0x02,0x37,0x05};unsigned char protocolmode[1] = {0x01};unsigned char hidinfo[4] = {0x01,0x11,0x00,0x02};int main() { unsigned char uuid[2],randadd[6]; if(init_blue("keymouse.txt") == 0) return(0); if(localnode() != 1) { printf("ERROR - Edit keymouse.txt to set ADDRESS = %s\n",device_address(localnode())); return(0); } // Write data to local characteristics uuid[0] = 0x2A; uuid[1] = 0x00; write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),name,3); uuid[0] = 0x2A; uuid[1] = 0x01; write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),appear,0); uuid[0] = 0x2A; uuid[1] = 0x4E; write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),protocolmode,0); uuid[0] = 0x2A; uuid[1] = 0x4A; write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),hidinfo,0); uuid[0] = 0x2A; uuid[1] = 0x4B; write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),reportmap,100); uuid[0] = 0x2A; uuid[1] = 0x4D; write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),report,0); uuid[0] = 0x2A; uuid[1] = 0x50; write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),pnpinfo,0); randadd[0] = 0xD3; randadd[1] = 0x56; randadd[2] = 0xD6; randadd[3] = 0x74; randadd[4] = 0x33; randadd[5] = 0x06; set_le_random_address(randadd); keys_to_callback(KEY_ON,0); set_le_wait(20000); le_pair(localnode(),JUST_WORKS,0); set_flags(FAST_TIMER,FLAG_ON); le_server(lecallback,20); close_all(); return(1); }int lecallback(int clientnode,int op,int cticn) { int n,nread; unsigned char buf[3]; static int timcount = 0; static int absx[4] = { 100,5000,5000,100 }; static int absy[4] = { 100,100,5000,5000 }; static int xyn = 0; if(op == LE_CONNECT) { printf("Connected OK\n"); timcount = 0; } if(op == LE_TIMER) { ++timcount; if(timcount == 50) { send_mouse(absx[xyn],absy[xyn]); ++xyn; if(xyn == 4) xyn = 0; timcount = 0; } } if(op == LE_KEYPRESS) { // cticn = ASCII code of key OR btferret custom code send_key(cticn); } if(op == LE_DISCONNECT) return(SERVER_EXIT); return(SERVER_CONTINUE); }int send_key(int key) { int n,hidcode; unsigned char buf[8]; static int reportindex = -1; // convert btferret code (key) to HID code hidcode = hid_key_code(key); if(hidcode == 0) return(0); if(reportindex < 0) { // look up Report1 index buf[0] = 0x2A; buf[1] = 0x4D; reportindex = find_ctic_index(localnode(),UUID_2,buf); if(reportindex < 0) { printf("Failed to find Report characteristic\n"); return(0); } } for(n = 0 ; n < 8 ; ++n) buf[n] = 0; // send key press to Report1 buf[0] = (hidcode >> 8) & 0xFF; // modifier buf[2] = hidcode & 0xFF; // key code write_ctic(localnode(),reportindex,buf,0); // send no key pressed - all zero buf[0] = 0; buf[2] = 0; write_ctic(localnode(),reportindex,buf,0); return(1); }int send_mouse(int x,int y) { unsigned char buf[5]; static int reportindex = -1; if(reportindex < 0) { // look up Report 1 index buf[0] = 0x2A; buf[1] = 0x4D; reportindex = find_ctic_index(localnode(),UUID_2,buf); if(reportindex < 0) { printf("Failed to find Report characteristic\n"); return(0); } ++reportindex; // Mouse is Report 2 } buf[0] = 0; buf[1] = x & 0xFF; buf[2] = (x >> 8) & 0xFF; buf[3] = y & 0xFF; buf[4] = (y >> 8) & 0xFF; // send to Report2 write_ctic(localnode(),reportindex,buf,5); return(1); }Statistics: Posted by petzval — Mon Mar 31, 2025 10:58 am