Firefly开源社区

标题: 添加服务 [打印本页]

作者: thong    时间: 2015-5-13 14:40
标题: 添加服务
大神们,你们好,我自己实现了一个服务和特征值,发现这个特征值能正常接收到ble助手这种通用的APP发的数据,当接收别的APP发的数据时gatt_write_cmd_ind_handler这个函数一点反应没有,不知道是什么问题?
作者: 安安    时间: 2015-5-13 15:49
别的APP指的是什么?这个APP是不是能够发现你所建立的服务并且对对应的特征值进行操作?
作者: thong    时间: 2015-5-13 15:56
安安 发表于 2015-5-13 15:49
别的APP指的是什么?这个APP是不是能够发现你所建立的服务并且对对应的特征值进行操作?

做的应用APP,可以发现服务和特征值,并且会返回写成功,就是固件这边没反应,但app没问题,因为我用TI的板子可以正常接收
作者: 安安    时间: 2015-5-13 16:07
如果对于LightBlue等等调试用的app都可以正常读写的话,我觉得可能更大的是出现在你们自己做的app上。
作者: thong    时间: 2015-5-13 16:12
安安 发表于 2015-5-13 16:07
如果对于LightBlue等等调试用的app都可以正常读写的话,我觉得可能更大的是出现在你们自己做的app上。

这个APP对应的TI版本的固件已经做好了,测试正常的,不知道是不是添加的服务和特征值有问题
作者: FireBLE_blue    时间: 2015-5-15 11:17
用LightBlue调试,如果用LightBlue写特征值,gatt_write_cmd_ind_handler函数得不到调用,应该考虑你的固件问题;检查程序。
建议下位机调试阶段都用LightBlue 读写。
作者: ydz    时间: 2015-5-27 11:45
楼主我现在参照防丢器程序在自己的工程中添加了自定义的服务,可是用lightblue搜索不到自定义服务,你能帮我分析下可能的原因吗?万分感谢
作者: FireBLE_blue    时间: 2015-5-27 14:28
ydz 发表于 2015-5-27 11:45
楼主我现在参照防丢器程序在自己的工程中添加了自定义的服务,可是用lightblue搜索不到自定义服务,你能帮 ...

添加的过程是怎样的,都加了那些代码,结果哪里与你想的结果不符,为什么与你想的不符,描述一下吧,亲,只有描述得够详细,才有得分析。
作者: ydz    时间: 2015-5-27 16:08
本帖最后由 ydz 于 2015-5-27 16:09 编辑
FireBLE_blue 发表于 2015-5-27 14:28
添加的过程是怎样的,都加了那些代码,结果哪里与你想的结果不符,为什么与你想的不符,描述一下吧,亲, ...
  1. 我基于 simple_periheral 工程
  2. 在attm.h 中添加
  3. USER_SERVICE =        0xfff1,
  4. USER_CHARACTERISTIC,        

  5. 在profile 里面添加了 test.h  test.c   test_task.h   test_task.c
  6. test.h 文件里面的部分内容
  7. enum
  8. {
  9. TEST_IDX_SVC,

  10. TEST_IDX_CHAR,
  11. TEST_IDX_DATA_VAL,

  12. TEST_IDX_NB,        
  13. };

  14. struct test_env_tag
  15. {
  16. struct prf_con_info con_info;
  17. uint16_t shdl;
  18. };

  19. //user Database Description
  20. extern const struct atts_desc test_att_db[TEST_IDX_NB];

  21. extern const atts_svc_desc_t test_svc;

  22. extern const struct atts_char_desc test_char;

  23. extern struct test_env_tag test_env;
  24. test.c

  25. const struct atts_desc test_att_db[TEST_IDX_NB] =
  26. {
  27. //User TEST Service Declaration
  28. [TEST_IDX_SVC] = {USER_SERVICE, PERM(RD, ENABLE), sizeof(test_svc),
  29. sizeof(test_svc), (uint8_t *)&test_svc},

  30. //test Characteristic Declaratoin        
  31. [TEST_IDX_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), sizeof(test_char),
  32. sizeof(test_char), (uint8_t *)&test_char},

  33. // test Characteristic Value
  34. [TEST_IDX_DATA_VAL] = {USER_CHARACTERISTIC, PERM(RD, ENABLE) | PERM(WR, ENABLE), sizeof(uint8_t),
  35. 0, NULL},        
  36. };

  37. const atts_svc_desc_t test_svc = USER_SERVICE;

  38. //User Service test data
  39. const struct atts_char_desc test_char = ATTS_CHAR(ATT_CHAR_PROP_RD | ATT_CHAR_PROP_WR,
  40. 0,
  41. USER_CHARACTERISTIC);



  42. struct test_env_tag test_env;

  43. void test_init(void)
  44. {
  45. // Reset Environment
  46. memset(&test_env, 0, sizeof(test_env));

  47. // Register USER TEST task into kernel
  48. task_test_desc_register();

  49. ke_state_set(TASK_USER, TEST_DISABLED);
  50. }

  51. void test_disable(void)
  52. {        
  53. // Disable testin database
  54. attsdb_svc_set_permission(test_env.shdl, PERM_RIGHT_DISABLE);

  55. struct test_disable_ind *ind = KE_MSG_ALLOC(TEST_DISABLE_IND,
  56. TASK_APP,
  57. TASK_USER,//test_env.con_info.appid, TASK_USER,
  58. test_disable_ind);

  59. //Fill in data
  60. ind->conhdl = TASK_APP;
  61. //Send the message
  62. ke_msg_send(ind);

  63. //Go to idle state
  64. ke_state_set(TASK_USER, TEST_IDLE);
  65. }


  66. test_task.h


  67. // Maximum number of Proximity Reporter task instances
  68. #define TEST_IDX_MAX (1)

  69. // Possible states of the test task
  70. enum
  71. {
  72. // Disabled State
  73. TEST_DISABLED,

  74. // Idle State
  75. TEST_IDLE,
  76. // Connected State

  77. TEST_CONNECTED,

  78. // Number of define State
  79. TEST_STATE_MAX
  80. };

  81. // Messages for Characteristic Reporter
  82. enum
  83. {
  84. // Start the Characteristic reporter
  85. TEST_ENABLE_REQ = KE_FIRST_MSG(TASK_USER),

  86. //Disable confirm
  87. TEST_DISABLE_IND,

  88. // Add Characteristic into the database
  89. TEST_CREATE_DB_REQ,

  90. // Inform APP of database creation status
  91. TEST_CREATE_DB_CFM,

  92. // Error Indicaton
  93. TEST_ERROR_IND
  94. };


  95. // Parameters of the CREATE_DB_REQ message
  96. struct test_create_db_req
  97. {
  98. // Indicate
  99. uint8_t features;
  100. };

  101. // Parameters of the ENABLE_REQ message
  102. struct test_enable_req
  103. {
  104. // Connection Handle
  105. uint16_t conhdl;
  106. // Security level
  107. uint8_t sec_lvl;
  108. // Saved user data to set in ATT DB
  109. uint8_t data;
  110. };


  111. // Parameters of the CREATE_DB_CFM message
  112. struct test_create_db_cfm
  113. {
  114. // States
  115. uint8_t status;
  116. };

  117. // Parameters of the DISABLE_IND message
  118. struct test_disable_ind
  119. {
  120. // Connection Hanle
  121. uint16_t conhdl;
  122. //user data
  123. uint8_t data;
  124. };


  125. extern const struct ke_state_handler test_state_handler[TEST_STATE_MAX];
  126. extern const struct ke_state_handler test_default_handler;
  127. extern ke_state_t test_state[TEST_IDX_MAX];

  128. extern void task_test_desc_register(void);

  129. test_task.c
  130. static int test_create_db_req_handler(ke_msg_id_t const msgid,
  131. struct test_create_db_req const *param,
  132. ke_task_id_t const dest_id,
  133. ke_task_id_t const src_id)
  134. {
  135. // Databsae Creation Status
  136. uint8_t status;

  137. // Save Profile ID
  138. test_env.con_info.prf_id = TASK_USER;

  139. /*---------------------------------------------------*
  140. * User Characteristic Creation
  141. *---------------------------------------------------*/        

  142. // Add Service Into Database
  143. status = atts_svc_create_db(&test_env.shdl, NULL, TEST_IDX_NB, NULL,
  144. dest_id, &test_att_db[0]);

  145. if(status == ATT_ERR_NO_ERROR)
  146. {
  147. attsdb_svc_set_permission(test_env.shdl, PERM(SVC, DISABLE));
  148. //If we are here, database has been fulfilled with success, go to idle state
  149. ke_state_set(TASK_USER, TEST_IDLE);
  150. }

  151. //Send CFM to application
  152. struct test_create_db_cfm * cfm = KE_MSG_ALLOC(TEST_CREATE_DB_CFM, src_id,
  153. TASK_USER, test_create_db_cfm );
  154. cfm->status = status;
  155. ke_msg_send(cfm);

  156. return (KE_MSG_CONSUMED);
  157. }        

  158. static int test_enable_req_handler(ke_msg_id_t const msgid,
  159. struct test_enable_req const *param,
  160. ke_task_id_t const dest_id,
  161. ke_task_id_t const src_id)
  162. {

  163. // Keep source of message, to respond to it furture on
  164. test_env.con_info.appid = src_id;
  165. // Strore the connection handle for which this profile is enable
  166. test_env.con_info.conhdl = param->conhdl;

  167. // Check if the provided connection exist
  168. if(gap_get_rec_idx(param->conhdl) == GAP_INVALID_CONIDX)
  169. {
  170. // The connection doesn't exist, request disallowed
  171. prf_server_error_ind_send((prf_env_struct *)&test_env, PRF_ERR_REQ_DISALLOWED,
  172. TEST_ERROR_IND, TEST_ENABLE_REQ);
  173. }
  174. else
  175. {

  176. //Enable Characteristic + Set Security Level
  177. attsdb_svc_set_permission(test_env.shdl, param->sec_lvl);

  178. //Set Characteristic specified value
  179. attsdb_att_set_value(test_env.shdl + TEST_IDX_DATA_VAL,
  180. sizeof(uint8_t), (uint8_t *)¶m->data);

  181. // Go to Connected state
  182. ke_state_set(TASK_USER, TEST_CONNECTED);
  183. }

  184. return (KE_MSG_CONSUMED);
  185. }


  186. static int gatt_write_cmd_ind_handler(ke_msg_id_t const msgid,
  187. struct gatt_write_cmd_ind const *param,
  188. ke_task_id_t const dest_id,
  189. ke_task_id_t const src_id)
  190. {

  191. if(param->conhdl == test_env.con_info.conhdl)
  192. {
  193. if(param->handle == test_env.shdl + TEST_IDX_DATA_VAL)
  194. {
  195. attsdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)¶m->value[0]);
  196. }
  197. }

  198. return (KE_MSG_CONSUMED);
  199. }


  200. static int gap_discon_cmp_evt_handler(ke_msg_id_t const msgid,
  201. struct gap_discon_cmp_evt const *param,
  202. ke_task_id_t const dest_id,
  203. ke_task_id_t const src_id)
  204. {

  205. // Check Connection Handle
  206. if(param->conhdl == test_env.con_info.conhdl)
  207. {
  208. // Abnormal reason - APP must alert to the level specified in the Alert Level Char.
  209. //        if ((param->reason != CO_ERROR_REMOTE_USER_TERM_CON) &&
  210. //        (param->reason != CO_ERROR_CON_TERM_BY_LOCAL_HOST))
  211. //        {        

  212. //        }
  213. test_disable();
  214. }

  215. return (KE_MSG_CONSUMED);
  216. }

  217. // Disable State handler definetion
  218. const struct ke_msg_handler test_disabled[] =
  219. {
  220. {TEST_CREATE_DB_REQ, (ke_msg_func_t)test_create_db_req_handler},
  221. };

  222. // Idle State handler definetion
  223. const struct ke_msg_handler test_idle[] =
  224. {
  225. {TEST_ENABLE_REQ, (ke_msg_func_t)test_enable_req_handler},
  226. };

  227. // Connected State handler definition
  228. const struct ke_msg_handler test_connected[] =
  229. {
  230. {GATT_WRITE_CMD_IND, (ke_msg_func_t)gatt_write_cmd_ind_handler},
  231. };

  232. // Default State handlers definition
  233. const struct ke_msg_handler test_default_state[] =
  234. {
  235. {GAP_DISCON_CMP_EVT, (ke_msg_func_t)gap_discon_cmp_evt_handler},
  236. };

  237. // Specifies the mssage handler structure for every input state
  238. const struct ke_state_handler test_state_handler[TEST_STATE_MAX] =
  239. {
  240. [TEST_DISABLED] = KE_STATE_HANDLER(test_disabled),
  241. [TEST_IDLE]        = KE_STATE_HANDLER_NONE,//KE_STATE_HANDLER(test_idle),
  242. [TEST_CONNECTED]        = KE_STATE_HANDLER(test_connected),        
  243. };

  244. // Specifies the message handlers that are common to all states
  245. const struct ke_state_handler test_default_handler = KE_STATE_HANDLER(test_default_state);

  246. // Defines the place holder for the states of all the task instances
  247. ke_state_t test_state[TEST_IDX_MAX];

  248. // Register test task into kernel
  249. void task_test_desc_register(void)
  250. {
  251. struct ke_task_desc task_test_desc;

  252. task_test_desc.state_handler = test_state_handler;
  253. task_test_desc.default_handler = &test_default_handler;
  254. task_test_desc.state = test_state;
  255. task_test_desc.state_max = TEST_STATE_MAX;
  256. task_test_desc.idx_max = TEST_IDX_MAX;

  257. task_desc_register(TASK_USER, task_test_desc);
  258. }

  259. app 里面添加 app_test.h app_test.c  app_test_task.h app_test_task.c
  260. app_test.c
  261. void app_test_create_db(uint8_t features)
  262. {
  263. struct test_create_db_req *msg = KE_MSG_ALLOC(TEST_CREATE_DB_REQ, TASK_USER, TASK_APP,
  264. test_create_db_req);
  265. msg->features = features;
  266. ke_msg_send(msg);
  267. }

  268. void app_test_enable_req(uint16_t conhdl, uint8_t sec_lvl, uint8_t data)
  269. {
  270. struct test_enable_req *msg = KE_MSG_ALLOC(TEST_ENABLE_REQ, TASK_USER, TASK_APP,
  271. test_enable_req);
  272. msg->conhdl = conhdl;
  273. msg->sec_lvl = sec_lvl;
  274. msg->data = data;
  275. ke_msg_send(msg);
  276. }

  277. app_test_task.c
  278. struct app_test_env_tag *app_test_env = &app_env.test_ev;

  279. int app_test_create_db_cfm_handler(ke_msg_id_t const msgid,
  280. struct test_create_db_cfm *param,
  281. ke_task_id_t const dest_id,
  282. ke_task_id_t const src_id)
  283. {
  284. if(param->status == ATT_ERR_NO_ERROR)
  285. {
  286. app_clear_local_service_flag(BLE_QPPS_SERVER_BIT);
  287. }

  288. return (KE_MSG_CONSUMED);
  289. }

  290. int app_test_disable_ind_handler(ke_msg_id_t const msgid,
  291. struct test_disable_ind *param,
  292. ke_task_id_t const dest_id,
  293. ke_task_id_t const src_id)
  294. {
  295. app_test_env->conhdl = 0xFFFF;
  296. app_test_env->enabled = false;

  297. return (KE_MSG_CONSUMED);
  298. }
复制代码




作者: ydz    时间: 2015-5-27 16:11
本帖最后由 ydz 于 2015-5-27 16:14 编辑
FireBLE_blue 发表于 2015-5-27 14:28
添加的过程是怎样的,都加了那些代码,结果哪里与你想的结果不符,为什么与你想的不符,描述一下吧,亲, ...
  1. app_until.c  app_get_local_service_flag 函数添加
  2. srv_flag |= BLE_QPPS_SERVER_BIT;

  3. app_env.c 修改
  4.     //app_set_scan_rsp_data(0);
  5.    app_set_scan_rsp_data(BLE_QPPS_SERVER_BIT);

  6. 函数 app_init(void)  添加
  7. app_test_init();

  8. static void app_test_init(void)
  9. {
  10.         app_test_env->conhdl = 0xFFFF;
  11. }

  12. prf_utils.c  prf_init() 函数添加
  13. test_init();

  14. app_task.c   const struct ke_msg_handler app_default_state[] =  里面添加
  15.     {TEST_DISABLE_IND,                     (ke_msg_func_t) app_test_disable_ind_handler},
  16.     {TEST_CREATE_DB_CFM,                   (ke_msg_func_t) app_test_create_db_cfm_handler},


  17. 我现在是不知道问题出在那里?
复制代码



作者: FireBLE_blue    时间: 2015-5-27 18:10
:'( 你还是把整个工程打包上来吧,看着蛋疼
作者: ydz    时间: 2015-5-28 09:33
FireBLE_blue 发表于 2015-5-27 18:10
你还是把整个工程打包上来吧,看着蛋疼

大哥,文档传不上来,我放网盘了  BLE TEST , 麻烦你帮忙看下。话说2540添加真心比这个方便,也容易理解....

作者: connycommy    时间: 2015-5-28 11:16
期待解决这个问题。
作者: FireBLE_blue    时间: 2015-5-28 11:51
本帖最后由 FireBLE_blue 于 2015-5-28 11:54 编辑
ydz 发表于 2015-5-28 09:33
大哥,文档传不上来,我放网盘了  BLE TEST , 麻烦你帮忙看下。话说2540添加真心比这个方便,也容易理解 ...

看了,我尝试改了好几处,还是没有成功,小改一下就挂了
作者: ydz    时间: 2015-5-28 12:16
FireBLE_blue 发表于 2015-5-28 11:51
看了,我尝试改了好几处,还是没有成功,小改一下就挂了

到现在还没有清楚添加流程,资料太少了! 并且改动的地方比较多。 大家一起研究各!
作者: ydz    时间: 2015-5-28 14:48
本帖最后由 ydz 于 2015-5-28 14:58 编辑
ydz 发表于 2015-5-28 12:16
到现在还没有清楚添加流程,资料太少了! 并且改动的地方比较多。 大家一起研究各!

问题找到了!    还是自己对协议栈不熟引起的, 做如下修改就可以了。

/// Full LLS Database Description - Used to add attributes into the database
const struct atts_desc proxr_lls_att_db[LLS_IDX_NB] =
{
    // Link Loss Service Declaration
[LLS_IDX_SVC]                      =   {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), sizeof(proxr_lls_svc)
                                        sizeof(proxr_lls_svc), (uint8_t *)&proxr_lls_svc


    // Alert Level Characteristic Declaration
    [LLS_IDX_ALERT_LVL_CHAR]        =   {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), sizeof(proxr_lls_alert_lvl_char),
                                         sizeof(proxr_lls_alert_lvl_char), (uint8_t *)&proxr_lls_alert_lvl_char},
    // Alert Level Characteristic Value
    [LLS_IDX_ALERT_LVL_VAL]         =   {ATT_CHAR_ALERT_LEVEL, PERM(RD, ENABLE) | PERM(WR, ENABLE), sizeof(uint8_t),
                                         0, NULL},
};
作者: FireBLE_blue    时间: 2015-5-28 15:46
:victory:
作者: connycommy    时间: 2015-5-29 10:08
ydz 发表于 2015-5-28 14:48
问题找到了!    还是自己对协议栈不熟引起的, 做如下修改就可以了。

/// Full LLS Database Descrip ...

楼主是贴出的上面的代码是怎么解决问题的,能详细说明一下吗?
作者: ydz    时间: 2015-5-29 17:42
connycommy 发表于 2015-5-29 10:08
楼主是贴出的上面的代码是怎么解决问题的,能详细说明一下吗?

这个说明在  BLE标准Core_v4.0   的 P1907.




欢迎光临 Firefly开源社区 (https://dev.t-firefly.com/) Powered by Discuz! X3.1