serial_service.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include "serial_service.h"
  2. #include "app_common.h"
  3. #include "ble.h"
  4. #include <furi.h>
  5. #define SERIAL_SERVICE_TAG "serial service"
  6. typedef struct {
  7. uint16_t svc_handle;
  8. uint16_t rx_char_handle;
  9. uint16_t tx_char_handle;
  10. } SerialSvc;
  11. static SerialSvc serial_svc;
  12. static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void *event) {
  13. SVCCTL_EvtAckStatus_t ret = SVCCTL_EvtNotAck;
  14. hci_event_pckt* event_pckt = (hci_event_pckt *)(((hci_uart_pckt*)event)->data);
  15. evt_blecore_aci* blecore_evt = (evt_blecore_aci*)event_pckt->data;
  16. aci_gatt_attribute_modified_event_rp0* attribute_modified;
  17. if(event_pckt->evt == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE) {
  18. if(blecore_evt->ecode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) {
  19. attribute_modified = (aci_gatt_attribute_modified_event_rp0*)blecore_evt->data;
  20. if(attribute_modified->Attr_Handle == serial_svc.tx_char_handle + 2) {
  21. // Descriptor handle
  22. ret = SVCCTL_EvtAckFlowEnable;
  23. FURI_LOG_D(SERIAL_SERVICE_TAG, "TX descriptor event");
  24. } else if(attribute_modified->Attr_Handle == serial_svc.tx_char_handle + 1) {
  25. FURI_LOG_I(SERIAL_SERVICE_TAG, "Data len: %d", attribute_modified->Attr_Data_Length);
  26. for(uint8_t i = 0; i < attribute_modified->Attr_Data_Length; i++) {
  27. printf("%02X ", attribute_modified->Attr_Data[i]);
  28. }
  29. printf("\r\n");
  30. serial_svc_update_rx(attribute_modified->Attr_Data, attribute_modified->Attr_Data_Length);
  31. ret = SVCCTL_EvtAckFlowEnable;
  32. }
  33. } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) {
  34. FURI_LOG_I(SERIAL_SERVICE_TAG, "Ack received", blecore_evt->ecode);
  35. ret = SVCCTL_EvtAckFlowEnable;
  36. }
  37. }
  38. return ret;
  39. }
  40. bool serial_svc_init() {
  41. tBleStatus status;
  42. const uint8_t service_uuid[] = {SERIAL_SVC_UUID_128};
  43. const uint8_t char_rx_uuid[] = {SERIAL_CHAR_RX_UUID_128};
  44. const uint8_t char_tx_uuid[] = {SERIAL_CHAR_TX_UUID_128};
  45. // Register event handler
  46. SVCCTL_RegisterSvcHandler(serial_svc_event_handler);
  47. // Add service
  48. status = aci_gatt_add_service(UUID_TYPE_128, (Service_UUID_t *)service_uuid, PRIMARY_SERVICE, 6, &serial_svc.svc_handle);
  49. if(status) {
  50. FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed to add Serial service: %d", status);
  51. }
  52. // Add TX characteristics
  53. status = aci_gatt_add_char(serial_svc.svc_handle, UUID_TYPE_128, (const Char_UUID_t*)char_tx_uuid ,
  54. SERIAL_SVC_DATA_LEN_MAX,
  55. CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE | CHAR_PROP_READ,
  56. ATTR_PERMISSION_NONE,
  57. GATT_NOTIFY_ATTRIBUTE_WRITE,
  58. 10,
  59. CHAR_VALUE_LEN_VARIABLE,
  60. &serial_svc.tx_char_handle);
  61. if(status) {
  62. FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed to add TX characteristic: %d", status);
  63. }
  64. // Add RX characteristic
  65. status = aci_gatt_add_char(serial_svc.svc_handle, UUID_TYPE_128, (const Char_UUID_t*)char_rx_uuid ,
  66. SERIAL_SVC_DATA_LEN_MAX,
  67. CHAR_PROP_READ | CHAR_PROP_INDICATE,
  68. ATTR_PERMISSION_NONE,
  69. GATT_DONT_NOTIFY_EVENTS,
  70. 10,
  71. CHAR_VALUE_LEN_VARIABLE,
  72. &serial_svc.rx_char_handle);
  73. if(status) {
  74. FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed to add RX characteristic: %d", status);
  75. }
  76. return status != BLE_STATUS_SUCCESS;
  77. }
  78. bool serial_svc_update_rx(uint8_t* data, uint8_t data_len) {
  79. furi_assert(data_len < SERIAL_SVC_DATA_LEN_MAX);
  80. tBleStatus result = aci_gatt_update_char_value(serial_svc.svc_handle,
  81. serial_svc.rx_char_handle,
  82. 0,
  83. data_len,
  84. data);
  85. if(result) {
  86. FURI_LOG_E(SERIAL_SERVICE_TAG, "Failed updating RX characteristic: %d", result);
  87. }
  88. return result != BLE_STATUS_SUCCESS;
  89. }