ble_lbs_app.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-09-27 WaterFishJ the first version
  9. */
  10. #include "bsal.h"
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include "bsal_osif.h"
  14. #include "bsal_srv_lbs.h"
  15. #define BSAL_STACK_NAME PKG_BSAL_STACK_NAME
  16. static void *bsal_stack_ptr = NULL;
  17. static uint16_t bsal_app_conn_handle;
  18. static rt_uint8_t gap_conn_state = BSAL_GAP_CONN_STATE_CONNECTED;
  19. static rt_uint8_t button_cccd_flag;
  20. static void bsa_app_set_adv_data(void *stack_ptr)
  21. {
  22. uint8_t tmp_data[32] = {0} ; //must be zero
  23. bsal_le_adv_data_add_flag(tmp_data, BSAL_GAP_ADTYPE_FLAGS_LIMITED | BSAL_GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED);
  24. char *adv_name = (char *)bsal_get_device_name(stack_ptr);
  25. bsal_adv_data_add_name(tmp_data, strlen(adv_name), adv_name);
  26. //bsal_adv_data_add_uuid16(tmp_data, BSAL_GATT_SERVICE_BATTERY_SERVICE);
  27. bsal_set_le_adv_data_user(stack_ptr, tmp_data);
  28. }
  29. static void bsal_app_all_callback(void *stack_ptr, uint8_t cb_layer, uint16_t cb_sub_event, uint8_t value_length, void *value)
  30. {
  31. T_BSAL_GAP_MSG_DATA *bsal_gap_msg_data = (T_BSAL_GAP_MSG_DATA *)value;
  32. uint8_t bd_addr[6];
  33. switch (cb_layer)
  34. {
  35. case BSAL_CB_LAYER_GAP:
  36. switch (cb_sub_event)
  37. {
  38. case BSAL_CB_STACK_READY:
  39. //get mac address
  40. bsal_osif_printf_info("============stack ready===========\r\n");
  41. bsa_app_set_adv_data(stack_ptr);
  42. bsal_stack_start_adv(stack_ptr);
  43. break;
  44. case BSAL_CB_CONNECT_STATUS:
  45. bsal_osif_printf_info("============stack connect id %d===========\r\n", bsal_gap_msg_data->gap_conn_state_change.conn_id);
  46. if (bsal_gap_msg_data->gap_conn_state_change.new_state == BSAL_GAP_CONN_STATE_CONNECTED)
  47. {
  48. bsal_app_conn_handle = bsal_gap_msg_data->gap_conn_state_change.conn_id;
  49. }
  50. else if (bsal_gap_msg_data->gap_conn_state_change.new_state == BSAL_GAP_CONN_STATE_DISCONNECTED)
  51. {
  52. bsal_stack_start_adv(stack_ptr);
  53. }
  54. bsal_osif_printf_info("BSAL: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
  55. bsal_gap_msg_data->gap_conn_state_change.conn_id, gap_conn_state, bsal_gap_msg_data->gap_conn_state_change.new_state, bsal_gap_msg_data->gap_conn_state_change.disc_cause);
  56. break;
  57. default:
  58. break;
  59. }
  60. if (cb_sub_event == BSAL_CB_STACK_READY)
  61. {
  62. //stack ready
  63. }
  64. break;
  65. case BSAL_CB_LAYER_GATT_PROFILE:
  66. switch (cb_sub_event)
  67. {
  68. //save the service start_handle
  69. //case uuid profile save start_handle
  70. //case SRV_CALLBACK66
  71. //save the identity
  72. }
  73. break;
  74. case BSAL_CB_LAYER_SM:
  75. break;
  76. case BSAL_CB_LAYER_COMMON:
  77. //connected save the connect id
  78. break;
  79. case BSAL_CB_LAYER_UNKNOWN:
  80. break;
  81. default:
  82. break;
  83. }
  84. }
  85. bool lbs_is_uuid(bsal_uuid_any_t *s, bsal_uuid_any_t *u)
  86. {
  87. if (s->u_type == u->u_type)
  88. {
  89. switch (s->u_type)
  90. {
  91. case BSAL_UUID_TYPE_128BIT:
  92. for (rt_uint8_t i = 0; i < 16; i++)
  93. {
  94. if (s->u128.value[i] != u->u128.value[i]) return false;
  95. }
  96. return true;
  97. case BSAL_UUID_TYPE_16BIT:
  98. break;
  99. case BSAL_UUID_TYPE_32BIT:
  100. break;
  101. default:
  102. return false;
  103. }
  104. }
  105. else return false;
  106. }
  107. static void bsal_app_profile_callback(void *p)
  108. {
  109. bsal_callbak_data_t *bsal_param = (bsal_callbak_data_t *)p;
  110. if (bsal_param->msg_type == BSAL_CALLBACK_TYPE_READ_CHAR_VALUE)
  111. {
  112. bsal_osif_printf_info("========callback read from %x====%x=======\r\n", bsal_param->off_handle, bsal_param->srv_uuid.u16.value);
  113. }
  114. else if (bsal_param->msg_type == BSAL_CALLBACK_TYPE_INDIFICATION_NOTIFICATION)
  115. {
  116. uint16_t cccbits = bsal_param->value;
  117. bsal_osif_printf_info("======callback notify from %x===data cccd %x====%x=====\r\n", bsal_param->off_handle, cccbits, bsal_param->srv_uuid.u16.value);
  118. if (lbs_is_uuid(&(bsal_param->srv_uuid), BSAL_UUID128_DECLARE(0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
  119. 0xDE, 0xEF, 0x12, 0x12, 0x23, 0x15, 0x00, 0x00)))//lbs_uuid
  120. {
  121. if (cccbits & BSAL_GATT_CCC_NOTIFY)
  122. {
  123. bsal_osif_printf_info("=========NOTIFY ENABLE from %x===data cccd %x====%x=====\r\n", bsal_param->off_handle, cccbits, bsal_param->srv_uuid.u16.value);
  124. }
  125. else
  126. {
  127. bsal_osif_printf_info("========NOTIFY DISABLE from %x===data cccd %x====%x=====\r\n", bsal_param->off_handle, cccbits, bsal_param->srv_uuid.u16.value);
  128. }
  129. }
  130. }
  131. else if (bsal_param->msg_type == BSAL_CALLBACK_TYPE_WRITE_CHAR_VALUE)
  132. {
  133. bsal_osif_printf_info("\r\n BSAL: THE DATA IS :%s\r\n", bsal_param->data);
  134. }
  135. }
  136. rt_sem_t button_sem = 0;
  137. void button_irq(void *p)
  138. {
  139. rt_sem_release(p);
  140. }
  141. void bsal_lbs_loop(void *p)
  142. {
  143. button_sem = rt_sem_create("button", 0, RT_IPC_FLAG_FIFO);
  144. rt_pin_mode(BUTTON_PIN, PIN_MODE_INPUT_PULLUP);
  145. rt_pin_attach_irq(BUTTON_PIN, PIN_IRQ_MODE_RISING_FALLING, button_irq, button_sem);
  146. rt_pin_irq_enable(BUTTON_PIN, PIN_IRQ_ENABLE);
  147. rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
  148. rt_pin_write(LED_PIN, PIN_HIGH);
  149. uint8_t flag = 0;
  150. while (1)
  151. {
  152. rt_sem_take(button_sem, RT_WAITING_FOREVER);
  153. if (button_cccd_flag)
  154. {
  155. flag = !rt_pin_read(BUTTON_PIN);
  156. bsal_lbs_send_notify_button(p, bsal_app_conn_handle, flag);
  157. }
  158. }
  159. }
  160. int bsal_lbs_app(void)
  161. {
  162. void *bsal_test_app_task = RT_NULL;
  163. void *stack_ptr = bsal_find_stack_ptr(BSAL_STACK_NAME);
  164. if (stack_ptr == NULL)
  165. {
  166. //print error;
  167. return 1;
  168. }
  169. //set iocapability
  170. bsal_stack_ptr = stack_ptr;
  171. //1. init stack
  172. bsal_stack_init(stack_ptr, bsal_app_all_callback); // init param not start stack
  173. // set device name
  174. char *device_name = "ble_rtt_lbs";
  175. bsal_set_device_name(stack_ptr, strlen(device_name), (uint8_t *)device_name);
  176. //2. bond type
  177. bsal_set_device_le_bond_type(stack_ptr, false, BSAL_NO_INPUT, BSAL_NO_OUTPUT, BSAL_GAP_AUTHEN_BIT_NO_BONDING, false);
  178. //set the bond flag:
  179. //3. service begin
  180. bsal_stack_le_srv_begin(stack_ptr, 1, bsal_app_profile_callback); //will add 1 service
  181. //4. lbs init
  182. bsal_le_lbs_svr_init(stack_ptr, bsal_app_profile_callback, &button_cccd_flag);
  183. //5. srv_end
  184. bsal_stack_le_srv_end(stack_ptr); //end srv add
  185. //6. start stack
  186. bsal_stack_startup(stack_ptr); //start she
  187. bsal_test_app_task = rt_thread_create("lbs_task", bsal_lbs_loop, stack_ptr, 2 * 256, 5, 10);
  188. if (bsal_test_app_task != RT_NULL)
  189. {
  190. rt_thread_startup(bsal_test_app_task);
  191. }
  192. return 0;
  193. }
  194. MSH_CMD_EXPORT_ALIAS(bsal_lbs_app, bsal_lbs_app, "bluetoooth LED Button sample");