@ -8,54 +8,138 @@
# include <zmk/hid.h>
# include <zmk/hid.h>
# include <zmk/usb.h>
# include <zmk/usb.h>
# include <zmk/hog.h>
# include <zmk/hog.h>
# include <zmk/event-manager.h>
# include <zmk/events/usb-conn-state-changed.h>
# include <logging/log.h>
# include <logging/log.h>
LOG_MODULE_DECLARE ( zmk , CONFIG_ZMK_LOG_LEVEL ) ;
LOG_MODULE_DECLARE ( zmk , CONFIG_ZMK_LOG_LEVEL ) ;
int zmk_endpoints_send_report ( u8_t usage_page ) {
enum endpoint {
int err ;
ENDPOINT_USB ,
struct zmk_hid_keypad_report * keypad_report ;
ENDPOINT_BLE ,
struct zmk_hid_consumer_report * consumer_report ;
} ;
LOG_DBG ( " usage page 0x%02X " , usage_page ) ;
switch ( usage_page ) {
static enum endpoint current_endpoint =
case USAGE_KEYPAD :
COND_CODE_1 ( IS_ENABLED ( CONFIG_ZMK_BLE ) , ( ENDPOINT_BLE ) , ( ENDPOINT_USB ) ) ;
keypad_report = zmk_hid_get_keypad_report ( ) ;
# ifdef CONFIG_ZMK_USB
static int send_keypad_report ( ) {
if ( zmk_usb_hid_send_report ( ( u8_t * ) keypad_report , sizeof ( struct zmk_hid_keypad_report ) ) ! =
struct zmk_hid_keypad_report * keypad_report = zmk_hid_get_keypad_report ( ) ;
0 ) {
LOG_DBG ( " USB Send Failed " ) ;
switch ( current_endpoint ) {
# if IS_ENABLED(CONFIG_ZMK_USB)
case ENDPOINT_USB : {
int err = zmk_usb_hid_send_report ( ( u8_t * ) keypad_report , sizeof ( * keypad_report ) ) ;
if ( err ) {
LOG_ERR ( " FAILED TO SEND OVER USB: %d " , err ) ;
}
}
# endif /* CONFIG_ZMK_USB */
return err ;
}
# endif /* IS_ENABLED(CONFIG_ZMK_USB) */
# ifdef CONFIG_ZMK_BLE
# if IS_ENABLED(CONFIG_ZMK_BLE)
err = zmk_hog_send_keypad_report ( & keypad_report - > body ) ;
case ENDPOINT_BLE : {
int err = zmk_hog_send_keypad_report ( & keypad_report - > body ) ;
if ( err ) {
if ( err ) {
LOG_ERR ( " FAILED TO SEND OVER HOG: %d " , err ) ;
LOG_ERR ( " FAILED TO SEND OVER HOG: %d " , err ) ;
}
}
# endif /* CONFIG_ZMK_BLE */
return err ;
}
# endif /* IS_ENABLED(CONFIG_ZMK_BLE) */
break ;
default :
case USAGE_CONSUMER :
LOG_ERR ( " Unsupported endpoint %d " , current_endpoint ) ;
consumer_report = zmk_hid_get_consumer_report ( ) ;
return - ENOTSUP ;
# ifdef CONFIG_ZMK_USB
}
if ( zmk_usb_hid_send_report ( ( u8_t * ) consumer_report ,
}
sizeof ( struct zmk_hid_consumer_report ) ) ! = 0 ) {
LOG_DBG ( " USB Send Failed " ) ;
static int send_consumer_report ( ) {
struct zmk_hid_consumer_report * consumer_report = zmk_hid_get_consumer_report ( ) ;
switch ( current_endpoint ) {
# if IS_ENABLED(CONFIG_ZMK_USB)
case ENDPOINT_USB : {
int err = zmk_usb_hid_send_report ( ( u8_t * ) consumer_report , sizeof ( * consumer_report ) ) ;
if ( err ) {
LOG_ERR ( " FAILED TO SEND OVER USB: %d " , err ) ;
}
}
# endif /* CONFIG_ZMK_USB */
return err ;
}
# endif /* IS_ENABLED(CONFIG_ZMK_USB) */
# ifdef CONFIG_ZMK_BLE
# if IS_ENABLED(CONFIG_ZMK_BLE)
err = zmk_hog_send_consumer_report ( & consumer_report - > body ) ;
case ENDPOINT_BLE : {
int err = zmk_hog_send_consumer_report ( & consumer_report - > body ) ;
if ( err ) {
if ( err ) {
LOG_ERR ( " FAILED TO SEND OVER HOG: %d " , err ) ;
LOG_ERR ( " FAILED TO SEND OVER HOG: %d " , err ) ;
}
}
# endif /* CONFIG_ZMK_BLE */
return err ;
}
# endif /* IS_ENABLED(CONFIG_ZMK_BLE) */
default :
LOG_ERR ( " Unsupported endpoint %d " , current_endpoint ) ;
return - ENOTSUP ;
}
}
int zmk_endpoints_send_report ( u8_t usage_page ) {
break ;
LOG_DBG ( " usage page 0x%02X " , usage_page ) ;
switch ( usage_page ) {
case USAGE_KEYPAD :
return send_keypad_report ( ) ;
case USAGE_CONSUMER :
return send_consumer_report ( ) ;
default :
default :
LOG_ERR ( " Unsupported usage page %d " , usage_page ) ;
LOG_ERR ( " Unsupported usage page %d " , usage_page ) ;
return - ENOTSUP ;
return - ENOTSUP ;
}
}
}
static bool is_usb_ready ( ) {
# if IS_ENABLED(CONFIG_ZMK_USB)
return zmk_usb_is_hid_ready ( ) ;
# else
return false ;
# endif
}
static bool is_ble_ready ( ) {
# if IS_ENABLED(CONFIG_ZMK_BLE)
return zmk_ble_active_profile_is_connected ( ) ;
# else
return false ;
# endif
}
static enum endpoint get_selected_endpoint ( ) {
if ( is_ble_ready ( ) ) {
if ( is_usb_ready ( ) ) {
LOG_DBG ( " Both endpoints ready. Selecting USB " ) ;
// TODO: add user setting to control this
return ENDPOINT_USB ;
}
return ENDPOINT_BLE ;
}
return ENDPOINT_USB ;
}
static int endpoint_listener ( const struct zmk_event_header * eh ) {
enum endpoint new_endpoint = get_selected_endpoint ( ) ;
if ( new_endpoint ! = current_endpoint ) {
// TODO: send null report on previous endpoint
current_endpoint = new_endpoint ;
LOG_INF ( " Endpoint changed: %d " , current_endpoint ) ;
}
return 0 ;
return 0 ;
}
}
ZMK_LISTENER ( endpoint_listener , endpoint_listener ) ;
# if IS_ENABLED(CONFIG_USB)
ZMK_SUBSCRIPTION ( endpoint_listener , usb_conn_state_changed ) ;
# endif
// TODO: add BLE state subscription