if-gatt.c 69 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666
  1. // SPDX-License-Identifier: Apache-2.0
  2. /*
  3. * Copyright (C) 2013 Intel Corporation
  4. *
  5. */
  6. #define _GNU_SOURCE
  7. #include <stdbool.h>
  8. #include <string.h>
  9. #include <hardware/bluetooth.h>
  10. #include "../hal-utils.h"
  11. #include "if-main.h"
  12. const btgatt_interface_t *if_gatt = NULL;
  13. /*
  14. * In version 19 some callback were changed.
  15. * btgatt_char_id_t -> btgatt_gatt_id_t
  16. * bt_uuid_t -> btgatt_gatt_id_t
  17. */
  18. #define str2btgatt_descr_id_t str2btgatt_gatt_id_t
  19. #define btgatt_descr_id_t2str btgatt_gatt_id_t2str
  20. #define btgatt_descr_id_t btgatt_gatt_id_t
  21. #define MAX_CHAR_ID_STR_LEN (MAX_UUID_STR_LEN + 3 + 11)
  22. #define MAX_SRVC_ID_STR_LEN (MAX_UUID_STR_LEN + 3 + 11 + 1 + 11)
  23. /* How man characters print from binary objects (arbitrary) */
  24. #define MAX_HEX_VAL_STR_LEN 100
  25. #define MAX_NOTIFY_PARAMS_STR_LEN (MAX_SRVC_ID_STR_LEN + MAX_CHAR_ID_STR_LEN \
  26. + MAX_ADDR_STR_LEN + MAX_HEX_VAL_STR_LEN + 60)
  27. #define MAX_READ_PARAMS_STR_LEN (MAX_SRVC_ID_STR_LEN + MAX_CHAR_ID_STR_LEN \
  28. + MAX_UUID_STR_LEN + MAX_HEX_VAL_STR_LEN + 80)
  29. /* Hex arguments must have "0x" or "0X" prefix */
  30. #define VERIFY_INT_ARG(n, v, err) \
  31. do { \
  32. if (n < argc) \
  33. v = strtol(argv[n], NULL, 0); \
  34. else { \
  35. haltest_error(err); \
  36. return;\
  37. } \
  38. } while (0)
  39. #define VERIFY_HEX_ARG(n, v, err) \
  40. do { \
  41. if (n < argc) \
  42. v = strtol(argv[n], NULL, 16); \
  43. else { \
  44. haltest_error(err); \
  45. return;\
  46. } \
  47. } while (0)
  48. /* Helper macros to verify arguments of methods */
  49. #define VERIFY_CLIENT_IF(n, v) VERIFY_INT_ARG(n, v, "No client_if specified\n")
  50. #define VERIFY_SERVER_IF(n, v) VERIFY_INT_ARG(n, v, "No server_if specified\n")
  51. #define VERIFY_CONN_ID(n, v) VERIFY_INT_ARG(n, v, "No conn_if specified\n")
  52. #define VERIFY_TRANS_ID(n, v) VERIFY_INT_ARG(n, v, "No trans_id specified\n")
  53. #define VERIFY_STATUS(n, v) VERIFY_INT_ARG(n, v, "No status specified\n")
  54. #define VERIFY_OFFSET(n, v) VERIFY_INT_ARG(n, v, "No offset specified\n")
  55. #define VERIFY_TEST_ARG(n, v) VERIFY_INT_ARG(n, v, "No test arg specified\n")
  56. #define VERIFY_ACTION(n, v) VERIFY_INT_ARG(n, v, "No action specified\n")
  57. #define VERIFY_FILT_TYPE(n, v) VERIFY_INT_ARG(n, v, "No filter specified\n")
  58. #define VERIFY_FILT_INDEX(n, v) VERIFY_INT_ARG(n, v, \
  59. "No filter index specified\n")
  60. #define VERIFY_FEAT_SELN(n, v) VERIFY_INT_ARG(n, v, "No feat seln specified\n")
  61. #define VERIFY_LIST_LOGIC_TYPE(n, v) VERIFY_INT_ARG(n, v, \
  62. "No list logic type specified\n")
  63. #define VERIFY_FILT_LOGIC_TYPE(n, v) VERIFY_INT_ARG(n, v, \
  64. "No filt logic type specified\n")
  65. #define VERIFY_RSSI_HI_THR(n, v) VERIFY_INT_ARG(n, v, \
  66. "No rssi hi threshold specified\n")
  67. #define VERIFY_RSSI_LOW_THR(n, v) VERIFY_INT_ARG(n, v, \
  68. "No low threshold specified\n")
  69. #define VERIFY_DELY_MODE(n, v) VERIFY_INT_ARG(n, v, "No delay mode specified\n")
  70. #define VERIFY_FND_TIME(n, v) VERIFY_INT_ARG(n, v, "No found time specified\n")
  71. #define VERIFY_LOST_TIME(n, v) VERIFY_INT_ARG(n, v, "No lost time specified\n")
  72. #define VERIFY_FND_TIME_CNT(n, v) VERIFY_INT_ARG(n, v, \
  73. "No found timer counter specified\n")
  74. #define VERIFY_COMP_ID(n, v) VERIFY_INT_ARG(n, v, "No company id specified\n")
  75. #define VERIFY_COMP_ID_MASK(n, v) VERIFY_INT_ARG(n, v, \
  76. "No comp. id mask specified\n")
  77. #define VERIFY_DATA_LEN(n, v) VERIFY_INT_ARG(n, v, "No data len specified\n")
  78. #define VERIFY_MASK_LEN(n, v) VERIFY_INT_ARG(n, v, "No mask len specified\n")
  79. #define VERIFY_MIN_INTERVAL(n, v) VERIFY_INT_ARG(n, v, \
  80. "No min interval specified\n")
  81. #define VERIFY_MAX_INTERVAL(n, v) VERIFY_INT_ARG(n, v, \
  82. "No max interval specified\n")
  83. #define VERIFY_APPEARANCE(n, v) VERIFY_INT_ARG(n, v, "No apperance specified\n")
  84. #define VERIFY_MANUFACTURER_LEN(n, v) VERIFY_INT_ARG(n, v, \
  85. "No manufacturer len specified\n")
  86. #define VERIFY_SERVICE_DATA_LEN(n, v) VERIFY_INT_ARG(n, v, \
  87. "No service data len specified\n")
  88. #define VERIFY_SERVICE_UUID_LEN(n, v) VERIFY_INT_ARG(n, v, \
  89. "No service uuid len specified\n")
  90. #define VERIFY_MTU(n, v) VERIFY_INT_ARG(n, v, "No mtu specified\n")
  91. #define VERIFY_LATENCY(n, v) VERIFY_INT_ARG(n, v, \
  92. "No latency specified\n")
  93. #define VERIFY_TIMEOUT(n, v) VERIFY_INT_ARG(n, v, "No timeout specified\n")
  94. #define VERIFY_SCAN_INTERVAL(n, v) VERIFY_INT_ARG(n, v, \
  95. "No scan interval specified\n")
  96. #define VERIFY_SCAN_WINDOW(n, v) VERIFY_INT_ARG(n, v, \
  97. "No scan window specified\n")
  98. #define VERIFY_ADV_TYPE(n, v) VERIFY_INT_ARG(n, v, \
  99. "No advertising type specified\n")
  100. #define VERIFY_CHNL_MAP(n, v) VERIFY_INT_ARG(n, v, \
  101. "No channel map specified\n")
  102. #define VERIFY_TX_POWER(n, v) VERIFY_INT_ARG(n, v, \
  103. "No tx power specified\n")
  104. #define VERIFY_TIMEOUT_S(n, v) VERIFY_INT_ARG(n, v, \
  105. "No timeout in sec specified\n")
  106. #define VERIFY_BATCH_SCAN_FULL_MAX(n, v) VERIFY_INT_ARG(n, v, \
  107. "No batch scan full max specified\n")
  108. #define VERIFY_BATCH_SCAN_TRUNC_MAX(n, v) VERIFY_INT_ARG(n, v, \
  109. "No batch scan trunc max specified\n")
  110. #define VERIFY_BATCH_SCAN_NOTIFY_THR(n, v) VERIFY_INT_ARG(n, v, \
  111. "No batch scan notify threshold specified\n")
  112. #define VERIFY_SCAN_MODE(n, v) VERIFY_INT_ARG(n, v, \
  113. "No scan mode specified\n")
  114. #define VERIFY_ADDR_TYPE(n, v) VERIFY_INT_ARG(n, v, \
  115. "No address type specified\n")
  116. #define VERIFY_DISCARD_RULE(n, v) VERIFY_INT_ARG(n, v, \
  117. "No discard rule specified\n")
  118. #define VERIFY_HANDLE(n, v) VERIFY_HEX_ARG(n, v, "No "#v" specified\n")
  119. #define VERIFY_SERVICE_HANDLE(n, v) VERIFY_HANDLE(n, v)
  120. #define VERIFY_UUID(n, v) \
  121. do { \
  122. if (n < argc) \
  123. gatt_str2bt_uuid_t(argv[n], -1, v); \
  124. else { \
  125. haltest_error("No uuid specified\n"); \
  126. return;\
  127. } \
  128. } while (0)
  129. #define VERIFY_SRVC_ID(n, v) \
  130. do { \
  131. if (n < argc) \
  132. str2btgatt_srvc_id_t(argv[n], v); \
  133. else { \
  134. haltest_error("No srvc_id specified\n"); \
  135. return;\
  136. } \
  137. } while (0)
  138. #define VERIFY_CHAR_ID(n, v) \
  139. do { \
  140. if (n < argc) \
  141. str2btgatt_gatt_id_t(argv[n], v); \
  142. else { \
  143. haltest_error("No char_id specified\n"); \
  144. return;\
  145. } \
  146. } while (0)
  147. #define VERIFY_DESCR_ID(n, v) \
  148. do { \
  149. if (n < argc) \
  150. str2btgatt_descr_id_t(argv[n], v); \
  151. else { \
  152. haltest_error("No descr_id specified\n"); \
  153. return;\
  154. } \
  155. } while (0)
  156. #define GET_VERIFY_HEX_STRING(i, v, l) \
  157. do { \
  158. int ll;\
  159. const char *n = argv[i]; \
  160. if (argc <= i) { \
  161. haltest_error("No value specified\n"); \
  162. return; \
  163. } \
  164. if (n[0] != '0' || (n[1] != 'X' && n[1] != 'x')) { \
  165. haltest_error("Value must be hex string\n"); \
  166. return; \
  167. } \
  168. ll = fill_buffer(n + 2, (uint8_t *) v, sizeof(v)); \
  169. if (ll < 0) { \
  170. haltest_error("Value must be byte hex string\n"); \
  171. return; \
  172. } \
  173. l = ll; \
  174. } while (0)
  175. /* Gatt uses little endian uuid */
  176. static const char GATT_BASE_UUID[] = {
  177. 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
  178. 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  179. };
  180. /*
  181. * converts gatt uuid to string
  182. * buf should be at least 39 bytes
  183. *
  184. * This function formats 16, 32 and 128 bits uuid
  185. *
  186. * returns string representation of uuid
  187. */
  188. static char *gatt_uuid_t2str(const bt_uuid_t *uuid, char *buf)
  189. {
  190. int shift = 0;
  191. int i = 16;
  192. int limit = 0;
  193. int j = 0;
  194. /* for bluetooth uuid only 32 bits */
  195. if (0 == memcmp(&uuid->uu, &GATT_BASE_UUID,
  196. sizeof(bt_uuid_t) - 4)) {
  197. limit = 12;
  198. /* make it 16 bits */
  199. if (uuid->uu[15] == 0 && uuid->uu[14] == 0)
  200. i = 14;
  201. }
  202. while (i-- > limit) {
  203. if (i == 11 || i == 9 || i == 7 || i == 5) {
  204. buf[j * 2 + shift] = '-';
  205. shift++;
  206. }
  207. sprintf(buf + j * 2 + shift, "%02x", uuid->uu[i]);
  208. ++j;
  209. }
  210. return buf;
  211. }
  212. /*
  213. * Tries to convert hex string of given size into out buffer.
  214. * Output buffer is little endian.
  215. */
  216. static void scan_field(const char *str, int len, uint8_t *out, int out_size)
  217. {
  218. int i;
  219. memset(out, 0, out_size);
  220. if (out_size * 2 > len + 1)
  221. out_size = (len + 1) / 2;
  222. for (i = 0; i < out_size && len > 0; ++i) {
  223. len -= 2;
  224. if (len >= 0)
  225. sscanf(str + len, "%02hhx", &out[i]);
  226. else
  227. sscanf(str, "%1hhx", &out[i]);
  228. }
  229. }
  230. /* Like strchr but with upper limit instead of 0 terminated string */
  231. static const char *strchrlimit(const char *p, const char *e, int c)
  232. {
  233. while (p < e && *p != (char) c)
  234. ++p;
  235. return p < e ? p : NULL;
  236. }
  237. /*
  238. * converts string to uuid
  239. * it accepts uuid in following forms:
  240. * 123
  241. * 0000123
  242. * 0000123-0014-1234-0000-000056789abc
  243. * 0000123001412340000000056789abc
  244. * 123-14-1234-0-56789abc
  245. */
  246. static void gatt_str2bt_uuid_t(const char *str, int len, bt_uuid_t *uuid)
  247. {
  248. int dash_cnt = 0;
  249. int dashes[6] = {-1}; /* indexes of '-' or \0 */
  250. static uint8_t filed_offset[] = { 16, 12, 10, 8, 6, 0 };
  251. const char *p = str;
  252. const char *e;
  253. int i;
  254. e = str + ((len >= 0) ? len : (int) strlen(str));
  255. while (p != NULL && dash_cnt < 5) {
  256. const char *f = strchrlimit(p, e, '-');
  257. if (f != NULL)
  258. dashes[++dash_cnt] = f++ - str;
  259. p = f;
  260. }
  261. /* get index of \0 to dashes table */
  262. if (dash_cnt < 5)
  263. dashes[++dash_cnt] = e - str;
  264. memcpy(uuid, GATT_BASE_UUID, sizeof(bt_uuid_t));
  265. /* whole uuid in one string without dashes */
  266. if (dash_cnt == 1 && dashes[1] > 8) {
  267. if (dashes[1] > 32)
  268. dashes[1] = 32;
  269. scan_field(str, dashes[1],
  270. &uuid->uu[16 - (dashes[1] + 1) / 2],
  271. (dashes[1] + 1) / 2);
  272. } else {
  273. for (i = 0; i < dash_cnt; ++i) {
  274. scan_field(str + dashes[i] + 1,
  275. dashes[i + 1] - dashes[i] - 1,
  276. &uuid->uu[filed_offset[i + 1]],
  277. filed_offset[i] - filed_offset[i + 1]);
  278. }
  279. }
  280. }
  281. /* char_id formating function */
  282. static char *btgatt_gatt_id_t2str(const btgatt_gatt_id_t *char_id, char *buf)
  283. {
  284. char uuid_buf[MAX_UUID_STR_LEN];
  285. sprintf(buf, "{%s,%d}", gatt_uuid_t2str(&char_id->uuid, uuid_buf),
  286. char_id->inst_id);
  287. return buf;
  288. }
  289. /* Parse btgatt_gatt_id_t */
  290. static void str2btgatt_gatt_id_t(const char *buf, btgatt_gatt_id_t *char_id)
  291. {
  292. const char *e;
  293. memcpy(&char_id->uuid, &GATT_BASE_UUID, sizeof(bt_uuid_t));
  294. char_id->inst_id = 0;
  295. if (*buf == '{')
  296. buf++;
  297. e = strpbrk(buf, " ,}");
  298. if (e == NULL)
  299. e = buf + strlen(buf);
  300. gatt_str2bt_uuid_t(buf, e - buf, &char_id->uuid);
  301. if (*e == ',') {
  302. buf = e + 1;
  303. e = strpbrk(buf, " ,}");
  304. if (e == NULL)
  305. e = buf + strlen(buf);
  306. if (buf < e)
  307. char_id->inst_id = atoi(buf);
  308. }
  309. }
  310. /* service_id formating function */
  311. static char *btgatt_srvc_id_t2str(const btgatt_srvc_id_t *srvc_id, char *buf)
  312. {
  313. char uuid_buf[MAX_UUID_STR_LEN];
  314. sprintf(buf, "{%s,%d,%d}", gatt_uuid_t2str(&srvc_id->id.uuid, uuid_buf),
  315. srvc_id->id.inst_id, srvc_id->is_primary);
  316. return buf;
  317. }
  318. /* Parse btgatt_srvc_id_t */
  319. static void str2btgatt_srvc_id_t(const char *buf, btgatt_srvc_id_t *srvc_id)
  320. {
  321. const char *e;
  322. memcpy(&srvc_id->id.uuid, &GATT_BASE_UUID, sizeof(bt_uuid_t));
  323. srvc_id->id.inst_id = 0;
  324. srvc_id->is_primary = 1;
  325. if (*buf == '{')
  326. buf++;
  327. e = strpbrk(buf, " ,}");
  328. if (e == NULL)
  329. e = buf + strlen(buf);
  330. gatt_str2bt_uuid_t(buf, e - buf, &srvc_id->id.uuid);
  331. if (*e == ',') {
  332. buf = e + 1;
  333. e = strpbrk(buf, " ,}");
  334. if (e == NULL)
  335. e = buf + strlen(buf);
  336. if (buf < e)
  337. srvc_id->id.inst_id = atoi(buf);
  338. }
  339. if (*e == ',') {
  340. buf = e + 1;
  341. e = strpbrk(buf, " ,}");
  342. if (e == NULL)
  343. e = buf + strlen(buf);
  344. if (buf < e)
  345. srvc_id->is_primary = atoi(buf);
  346. }
  347. }
  348. /* Converts array of uint8_t to string representation */
  349. static char *array2str(const uint8_t *v, int size, char *buf, int out_size)
  350. {
  351. int limit = size;
  352. int i;
  353. if (out_size > 0) {
  354. *buf = '\0';
  355. if (size >= 2 * out_size)
  356. limit = (out_size - 2) / 2;
  357. for (i = 0; i < limit; ++i)
  358. sprintf(buf + 2 * i, "%02x", v[i]);
  359. /* output buffer not enough to hold whole field fill with ...*/
  360. if (limit < size)
  361. sprintf(buf + 2 * i, "...");
  362. }
  363. return buf;
  364. }
  365. /* Converts btgatt_notify_params_t to string */
  366. static char *btgatt_notify_params_t2str(const btgatt_notify_params_t *data,
  367. char *buf)
  368. {
  369. char addr[MAX_ADDR_STR_LEN];
  370. char srvc_id[MAX_SRVC_ID_STR_LEN];
  371. char char_id[MAX_CHAR_ID_STR_LEN];
  372. char value[MAX_HEX_VAL_STR_LEN];
  373. sprintf(buf, "{bda=%s, srvc_id=%s, char_id=%s, val=%s, is_notify=%u}",
  374. bt_bdaddr_t2str(&data->bda, addr),
  375. btgatt_srvc_id_t2str(&data->srvc_id, srvc_id),
  376. btgatt_gatt_id_t2str(&data->char_id, char_id),
  377. array2str(data->value, data->len, value, sizeof(value)),
  378. data->is_notify);
  379. return buf;
  380. }
  381. static char *btgatt_unformatted_value_t2str(const btgatt_unformatted_value_t *v,
  382. char *buf, int size)
  383. {
  384. return array2str(v->value, v->len, buf, size);
  385. }
  386. static char *btgatt_read_params_t2str(const btgatt_read_params_t *data,
  387. char *buf)
  388. {
  389. char srvc_id[MAX_SRVC_ID_STR_LEN];
  390. char char_id[MAX_CHAR_ID_STR_LEN];
  391. char descr_id[MAX_UUID_STR_LEN];
  392. char value[MAX_HEX_VAL_STR_LEN];
  393. sprintf(buf, "{srvc_id=%s, char_id=%s, descr_id=%s, val=%s value_type=%d, status=%d}",
  394. btgatt_srvc_id_t2str(&data->srvc_id, srvc_id),
  395. btgatt_gatt_id_t2str(&data->char_id, char_id),
  396. btgatt_descr_id_t2str(&data->descr_id, descr_id),
  397. btgatt_unformatted_value_t2str(&data->value, value, 100),
  398. data->value_type, data->status);
  399. return buf;
  400. }
  401. /* BT-GATT Client callbacks. */
  402. /* Cache client_if and conn_id for tab completion */
  403. static char client_if_str[20];
  404. static char conn_id_str[20];
  405. /* Cache address for tab completion */
  406. static char last_addr[MAX_ADDR_STR_LEN];
  407. /* Callback invoked in response to register_client */
  408. static void gattc_register_client_cb(int status, int client_if,
  409. bt_uuid_t *app_uuid)
  410. {
  411. char buf[MAX_UUID_STR_LEN];
  412. snprintf(client_if_str, sizeof(client_if_str), "%d", client_if);
  413. haltest_info("%s: status=%d client_if=%d app_uuid=%s\n", __func__,
  414. status, client_if,
  415. gatt_uuid_t2str(app_uuid, buf));
  416. }
  417. /* Callback for scan results */
  418. static void gattc_scan_result_cb(bt_bdaddr_t *bda, int rssi, uint8_t *adv_data)
  419. {
  420. char buf[MAX_ADDR_STR_LEN];
  421. haltest_info("%s: bda=%s rssi=%d adv_data=%p\n", __func__,
  422. bt_bdaddr_t2str(bda, buf), rssi, adv_data);
  423. }
  424. /* GATT open callback invoked in response to open */
  425. static void gattc_connect_cb(int conn_id, int status, int client_if,
  426. bt_bdaddr_t *bda)
  427. {
  428. haltest_info("%s: conn_id=%d status=%d, client_if=%d bda=%s\n",
  429. __func__, conn_id, status, client_if,
  430. bt_bdaddr_t2str(bda, last_addr));
  431. }
  432. /* Callback invoked in response to close */
  433. static void gattc_disconnect_cb(int conn_id, int status, int client_if,
  434. bt_bdaddr_t *bda)
  435. {
  436. char buf[MAX_ADDR_STR_LEN];
  437. haltest_info("%s: conn_id=%d status=%d, client_if=%d bda=%s\n",
  438. __func__, conn_id, status, client_if,
  439. bt_bdaddr_t2str(bda, buf));
  440. }
  441. /*
  442. * Invoked in response to search_service when the GATT service search
  443. * has been completed.
  444. */
  445. static void gattc_search_complete_cb(int conn_id, int status)
  446. {
  447. haltest_info("%s: conn_id=%d status=%d\n", __func__, conn_id, status);
  448. }
  449. /* Reports GATT services on a remote device */
  450. static void gattc_search_result_cb(int conn_id, btgatt_srvc_id_t *srvc_id)
  451. {
  452. char srvc_id_buf[MAX_SRVC_ID_STR_LEN];
  453. haltest_info("%s: conn_id=%d srvc_id=%s\n", __func__, conn_id,
  454. btgatt_srvc_id_t2str(srvc_id, srvc_id_buf));
  455. }
  456. /* GATT characteristic enumeration result callback */
  457. static void gattc_get_characteristic_cb(int conn_id, int status,
  458. btgatt_srvc_id_t *srvc_id,
  459. btgatt_gatt_id_t *char_id,
  460. int char_prop)
  461. {
  462. char srvc_id_buf[MAX_SRVC_ID_STR_LEN];
  463. char char_id_buf[MAX_CHAR_ID_STR_LEN];
  464. haltest_info("%s: conn_id=%d status=%d srvc_id=%s char_id=%s, char_prop=0x%x\n",
  465. __func__, conn_id, status,
  466. btgatt_srvc_id_t2str(srvc_id, srvc_id_buf),
  467. btgatt_gatt_id_t2str(char_id, char_id_buf), char_prop);
  468. /* enumerate next characteristic */
  469. if (status == 0)
  470. EXEC(if_gatt->client->get_characteristic, conn_id, srvc_id,
  471. char_id);
  472. }
  473. /* GATT descriptor enumeration result callback */
  474. static void gattc_get_descriptor_cb(int conn_id, int status,
  475. btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
  476. btgatt_descr_id_t *descr_id)
  477. {
  478. char buf[MAX_UUID_STR_LEN];
  479. char srvc_id_buf[MAX_SRVC_ID_STR_LEN];
  480. char char_id_buf[MAX_CHAR_ID_STR_LEN];
  481. haltest_info("%s: conn_id=%d status=%d srvc_id=%s char_id=%s, descr_id=%s\n",
  482. __func__, conn_id, status,
  483. btgatt_srvc_id_t2str(srvc_id, srvc_id_buf),
  484. btgatt_gatt_id_t2str(char_id, char_id_buf),
  485. btgatt_descr_id_t2str(descr_id, buf));
  486. if (status == 0)
  487. EXEC(if_gatt->client->get_descriptor, conn_id, srvc_id, char_id,
  488. descr_id);
  489. }
  490. /* GATT included service enumeration result callback */
  491. static void gattc_get_included_service_cb(int conn_id, int status,
  492. btgatt_srvc_id_t *srvc_id,
  493. btgatt_srvc_id_t *incl_srvc_id)
  494. {
  495. char srvc_id_buf[MAX_SRVC_ID_STR_LEN];
  496. char incl_srvc_id_buf[MAX_SRVC_ID_STR_LEN];
  497. haltest_info("%s: conn_id=%d status=%d srvc_id=%s incl_srvc_id=%s)\n",
  498. __func__, conn_id, status,
  499. btgatt_srvc_id_t2str(srvc_id, srvc_id_buf),
  500. btgatt_srvc_id_t2str(incl_srvc_id, incl_srvc_id_buf));
  501. if (status == 0)
  502. EXEC(if_gatt->client->get_included_service, conn_id, srvc_id,
  503. incl_srvc_id);
  504. }
  505. /* Callback invoked in response to [de]register_for_notification */
  506. static void gattc_register_for_notification_cb(int conn_id, int registered,
  507. int status,
  508. btgatt_srvc_id_t *srvc_id,
  509. btgatt_gatt_id_t *char_id)
  510. {
  511. char srvc_id_buf[MAX_SRVC_ID_STR_LEN];
  512. char char_id_buf[MAX_CHAR_ID_STR_LEN];
  513. haltest_info("%s: conn_id=%d registered=%d status=%d srvc_id=%s char_id=%s\n",
  514. __func__, conn_id, registered, status,
  515. btgatt_srvc_id_t2str(srvc_id, srvc_id_buf),
  516. btgatt_gatt_id_t2str(char_id, char_id_buf));
  517. }
  518. /*
  519. * Remote device notification callback, invoked when a remote device sends
  520. * a notification or indication that a client has registered for.
  521. */
  522. static void gattc_notify_cb(int conn_id, btgatt_notify_params_t *p_data)
  523. {
  524. char buf[MAX_NOTIFY_PARAMS_STR_LEN];
  525. haltest_info("%s: conn_id=%d data=%s\n", __func__, conn_id,
  526. btgatt_notify_params_t2str(p_data, buf));
  527. }
  528. /* Reports result of a GATT read operation */
  529. static void gattc_read_characteristic_cb(int conn_id, int status,
  530. btgatt_read_params_t *p_data)
  531. {
  532. char buf[MAX_READ_PARAMS_STR_LEN];
  533. haltest_info("%s: conn_id=%d status=%d data=%s\n", __func__, conn_id,
  534. status, btgatt_read_params_t2str(p_data, buf));
  535. }
  536. /* GATT write characteristic operation callback */
  537. static void gattc_write_characteristic_cb(int conn_id, int status,
  538. btgatt_write_params_t *p_data)
  539. {
  540. haltest_info("%s: conn_id=%d status=%d\n", __func__, conn_id, status);
  541. }
  542. /* GATT execute prepared write callback */
  543. static void gattc_execute_write_cb(int conn_id, int status)
  544. {
  545. haltest_info("%s: conn_id=%d status=%d\n", __func__, conn_id, status);
  546. }
  547. /* Callback invoked in response to read_descriptor */
  548. static void gattc_read_descriptor_cb(int conn_id, int status,
  549. btgatt_read_params_t *p_data)
  550. {
  551. char buf[MAX_READ_PARAMS_STR_LEN];
  552. haltest_info("%s: conn_id=%d status=%d data=%s\n", __func__, conn_id,
  553. status, btgatt_read_params_t2str(p_data, buf));
  554. }
  555. /* Callback invoked in response to write_descriptor */
  556. static void gattc_write_descriptor_cb(int conn_id, int status,
  557. btgatt_write_params_t *p_data)
  558. {
  559. haltest_info("%s: conn_id=%d status=%d\n", __func__, conn_id, status);
  560. }
  561. /* Callback triggered in response to read_remote_rssi */
  562. static void gattc_read_remote_rssi_cb(int client_if, bt_bdaddr_t *bda, int rssi,
  563. int status)
  564. {
  565. char buf[MAX_ADDR_STR_LEN];
  566. haltest_info("%s: client_if=%d bda=%s rssi=%d satus=%d\n", __func__,
  567. client_if, bt_bdaddr_t2str(bda, buf), rssi, status);
  568. }
  569. /* Callback invoked in response to listen */
  570. static void gattc_listen_cb(int status, int client_if)
  571. {
  572. haltest_info("%s: client_if=%d status=%d\n", __func__, client_if,
  573. status);
  574. }
  575. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  576. /* Callback invoked when the MTU for a given connection changes */
  577. static void gattc_configure_mtu_cb(int conn_id, int status, int mtu)
  578. {
  579. haltest_info("%s: conn_id=%d, status=%d, mtu=%d\n", __func__, conn_id,
  580. status, mtu);
  581. }
  582. /* Callback invoked when a scan filter configuration command has completed */
  583. static void gattc_scan_filter_cfg_cb(int action, int client_if, int status,
  584. int filt_type, int avbl_space)
  585. {
  586. haltest_info("%s: action=%d, client_if=%d, status=%d, filt_type=%d"
  587. ", avbl_space=%d", __func__, action, client_if, status,
  588. filt_type, avbl_space);
  589. }
  590. /* Callback invoked when scan param has been added, cleared, or deleted */
  591. static void gattc_scan_filter_param_cb(int action, int client_if, int status,
  592. int avbl_space)
  593. {
  594. haltest_info("%s: action=%d, client_if=%d, status=%d, avbl_space=%d",
  595. __func__, action, client_if, status, avbl_space);
  596. }
  597. /* Callback invoked when a scan filter configuration command has completed */
  598. static void gattc_scan_filter_status_cb(int enable, int client_if, int status)
  599. {
  600. haltest_info("%s: enable=%d, client_if=%d, status=%d", __func__,
  601. enable, client_if, status);
  602. }
  603. /* Callback invoked when multi-adv enable operation has completed */
  604. static void gattc_multi_adv_enable_cb(int client_if, int status)
  605. {
  606. haltest_info("%s: client_if=%d, status=%d", __func__, client_if,
  607. status);
  608. }
  609. /* Callback invoked when multi-adv param update operation has completed */
  610. static void gattc_multi_adv_update_cb(int client_if, int status)
  611. {
  612. haltest_info("%s: client_if=%d, status=%d", __func__, client_if,
  613. status);
  614. }
  615. /* Callback invoked when multi-adv instance data set operation has completed */
  616. static void gattc_multi_adv_data_cb(int client_if, int status)
  617. {
  618. haltest_info("%s: client_if=%d, status=%d", __func__, client_if,
  619. status);
  620. }
  621. /* Callback invoked when multi-adv disable operation has completed */
  622. static void gattc_multi_adv_disable_cb(int client_if, int status)
  623. {
  624. haltest_info("%s: client_if=%d, status=%d", __func__, client_if,
  625. status);
  626. }
  627. /*
  628. * Callback notifying an application that a remote device connection is
  629. * currently congested and cannot receive any more data. An application should
  630. * avoid sending more data until a further callback is received indicating the
  631. * congestion status has been cleared.
  632. */
  633. static void gattc_congestion_cb(int conn_id, bool congested)
  634. {
  635. haltest_info("%s: conn_id=%d, congested=%d", __func__, conn_id,
  636. congested);
  637. }
  638. /* Callback invoked when batchscan storage config operation has completed */
  639. static void gattc_batchscan_cfg_storage_cb(int client_if, int status)
  640. {
  641. haltest_info("%s: client_if=%d, status=%d", __func__, client_if,
  642. status);
  643. }
  644. /* Callback invoked when batchscan enable / disable operation has completed */
  645. static void gattc_batchscan_enable_disable_cb(int action, int client_if,
  646. int status)
  647. {
  648. haltest_info("%s: action=%d, client_if=%d, status=%d", __func__, action,
  649. client_if, status);
  650. }
  651. /* Callback invoked when batchscan reports are obtained */
  652. static void gattc_batchscan_reports_cb(int client_if, int status,
  653. int report_format, int num_records,
  654. int data_len, uint8_t* rep_data)
  655. {
  656. /* BTGATT_MAX_ATTR_LEN = 600 */
  657. char valbuf[600];
  658. haltest_info("%s: client_if=%d, status=%d, report_format=%d"
  659. ", num_records=%d, data_len=%d, rep_data=%s", __func__,
  660. client_if, status, report_format, num_records, data_len,
  661. array2str(rep_data, data_len, valbuf, sizeof(valbuf)));
  662. }
  663. /* Callback invoked when batchscan storage threshold limit is crossed */
  664. static void gattc_batchscan_threshold_cb(int client_if)
  665. {
  666. haltest_info("%s: client_if=%d", __func__, client_if);
  667. }
  668. /* Track ADV VSE callback invoked when tracked device is found or lost */
  669. static void gattc_track_adv_event_cb(int client_if, int filt_index,
  670. int addr_type, bt_bdaddr_t* bda,
  671. int adv_state)
  672. {
  673. char buf[MAX_ADDR_STR_LEN];
  674. haltest_info("%s, client_if=%d, filt_index=%d, addr_type=%d, bda=%s"
  675. ", adv_state=%d", __func__, client_if, filt_index,
  676. addr_type, bt_bdaddr_t2str(bda, buf), adv_state);
  677. }
  678. #endif
  679. static const btgatt_client_callbacks_t btgatt_client_callbacks = {
  680. .register_client_cb = gattc_register_client_cb,
  681. .scan_result_cb = gattc_scan_result_cb,
  682. .open_cb = gattc_connect_cb,
  683. .close_cb = gattc_disconnect_cb,
  684. .search_complete_cb = gattc_search_complete_cb,
  685. .search_result_cb = gattc_search_result_cb,
  686. .get_characteristic_cb = gattc_get_characteristic_cb,
  687. .get_descriptor_cb = gattc_get_descriptor_cb,
  688. .get_included_service_cb = gattc_get_included_service_cb,
  689. .register_for_notification_cb = gattc_register_for_notification_cb,
  690. .notify_cb = gattc_notify_cb,
  691. .read_characteristic_cb = gattc_read_characteristic_cb,
  692. .write_characteristic_cb = gattc_write_characteristic_cb,
  693. .read_descriptor_cb = gattc_read_descriptor_cb,
  694. .write_descriptor_cb = gattc_write_descriptor_cb,
  695. .execute_write_cb = gattc_execute_write_cb,
  696. .read_remote_rssi_cb = gattc_read_remote_rssi_cb,
  697. .listen_cb = gattc_listen_cb,
  698. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  699. .configure_mtu_cb = gattc_configure_mtu_cb,
  700. .scan_filter_cfg_cb = gattc_scan_filter_cfg_cb,
  701. .scan_filter_param_cb = gattc_scan_filter_param_cb,
  702. .scan_filter_status_cb = gattc_scan_filter_status_cb,
  703. .multi_adv_enable_cb = gattc_multi_adv_enable_cb,
  704. .multi_adv_update_cb = gattc_multi_adv_update_cb,
  705. .multi_adv_data_cb = gattc_multi_adv_data_cb,
  706. .multi_adv_disable_cb = gattc_multi_adv_disable_cb,
  707. .congestion_cb = gattc_congestion_cb,
  708. .batchscan_cfg_storage_cb = gattc_batchscan_cfg_storage_cb,
  709. .batchscan_enb_disable_cb = gattc_batchscan_enable_disable_cb,
  710. .batchscan_reports_cb = gattc_batchscan_reports_cb,
  711. .batchscan_threshold_cb = gattc_batchscan_threshold_cb,
  712. .track_adv_event_cb = gattc_track_adv_event_cb,
  713. #endif
  714. };
  715. /* BT-GATT Server callbacks */
  716. /* Cache server_if and conn_id for tab completion */
  717. static char server_if_str[20];
  718. /* Callback invoked in response to register_server */
  719. static void gatts_register_server_cb(int status, int server_if,
  720. bt_uuid_t *app_uuid)
  721. {
  722. char buf[MAX_UUID_STR_LEN];
  723. haltest_info("%s: status=%d server_if=%d app_uuid=%s\n", __func__,
  724. status, server_if, gatt_uuid_t2str(app_uuid, buf));
  725. }
  726. /*
  727. * Callback indicating that a remote device has connected
  728. * or been disconnected
  729. */
  730. static void gatts_connection_cb(int conn_id, int server_if, int connected,
  731. bt_bdaddr_t *bda)
  732. {
  733. haltest_info("%s: conn_id=%d server_if=%d connected=%d bda=%s\n",
  734. __func__, conn_id, server_if, connected,
  735. bt_bdaddr_t2str(bda, last_addr));
  736. snprintf(conn_id_str, sizeof(conn_id_str), "%d", conn_id);
  737. }
  738. /* Callback invoked in response to create_service */
  739. static void gatts_service_added_cb(int status, int server_if,
  740. btgatt_srvc_id_t *srvc_id, int srvc_handle)
  741. {
  742. char buf[MAX_SRVC_ID_STR_LEN];
  743. snprintf(server_if_str, sizeof(server_if_str), "%d", server_if);
  744. haltest_info("%s: status=%d server_if=%d srvc_id=%s handle=0x%x\n",
  745. __func__, status, server_if,
  746. btgatt_srvc_id_t2str(srvc_id, buf), srvc_handle);
  747. }
  748. /* Callback indicating that an included service has been added to a service */
  749. static void gatts_included_service_added_cb(int status, int server_if,
  750. int srvc_handle,
  751. int incl_srvc_handle)
  752. {
  753. haltest_info("%s: status=%d server_if=%d srvc_handle=0x%x inc_srvc_handle=0x%x\n",
  754. __func__, status, server_if,
  755. srvc_handle, incl_srvc_handle);
  756. }
  757. /* Callback invoked when a characteristic has been added to a service */
  758. static void gatts_characteristic_added_cb(int status, int server_if,
  759. bt_uuid_t *uuid,
  760. int srvc_handle,
  761. int char_handle)
  762. {
  763. char buf[MAX_SRVC_ID_STR_LEN];
  764. haltest_info("%s: status=%d server_if=%d uuid=%s srvc_handle=0x%x char_handle=0x%x\n",
  765. __func__, status, server_if, gatt_uuid_t2str(uuid, buf),
  766. srvc_handle, char_handle);
  767. }
  768. /* Callback invoked when a descriptor has been added to a characteristic */
  769. static void gatts_descriptor_added_cb(int status, int server_if,
  770. bt_uuid_t *uuid, int srvc_handle,
  771. int descr_handle)
  772. {
  773. char buf[MAX_SRVC_ID_STR_LEN];
  774. haltest_info("%s: status=%d server_if=%d uuid=%s srvc_handle=0x%x descr_handle=0x%x\n",
  775. __func__, status, server_if, gatt_uuid_t2str(uuid, buf),
  776. srvc_handle, descr_handle);
  777. }
  778. /* Callback invoked in response to start_service */
  779. static void gatts_service_started_cb(int status, int server_if, int srvc_handle)
  780. {
  781. haltest_info("%s: status=%d server_if=%d srvc_handle=0x%x\n",
  782. __func__, status, server_if, srvc_handle);
  783. }
  784. /* Callback invoked in response to stop_service */
  785. static void gatts_service_stopped_cb(int status, int server_if, int srvc_handle)
  786. {
  787. haltest_info("%s: status=%d server_if=%d srvc_handle=0x%x\n",
  788. __func__, status, server_if, srvc_handle);
  789. }
  790. /* Callback triggered when a service has been deleted */
  791. static void gatts_service_deleted_cb(int status, int server_if, int srvc_handle)
  792. {
  793. haltest_info("%s: status=%d server_if=%d srvc_handle=0x%x\n",
  794. __func__, status, server_if, srvc_handle);
  795. }
  796. /*
  797. * Callback invoked when a remote device has requested to read a characteristic
  798. * or descriptor. The application must respond by calling send_response
  799. */
  800. static void gatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda,
  801. int attr_handle, int offset,
  802. bool is_long)
  803. {
  804. char buf[MAX_ADDR_STR_LEN];
  805. haltest_info("%s: conn_id=%d trans_id=%d bda=%s attr_handle=0x%x offset=%d is_long=%d\n",
  806. __func__, conn_id, trans_id, bt_bdaddr_t2str(bda, buf),
  807. attr_handle, offset, is_long);
  808. }
  809. /*
  810. * Callback invoked when a remote device has requested to write to a
  811. * characteristic or descriptor.
  812. */
  813. static void gatts_request_write_cb(int conn_id, int trans_id, bt_bdaddr_t *bda,
  814. int attr_handle, int offset, int length,
  815. bool need_rsp, bool is_prep,
  816. uint8_t *value)
  817. {
  818. char buf[MAX_ADDR_STR_LEN];
  819. char valbuf[100];
  820. haltest_info("%s: conn_id=%d trans_id=%d bda=%s attr_handle=0x%x offset=%d length=%d need_rsp=%d is_prep=%d value=%s\n",
  821. __func__, conn_id, trans_id, bt_bdaddr_t2str(bda, buf),
  822. attr_handle, offset, length, need_rsp, is_prep,
  823. array2str(value, length, valbuf, sizeof(valbuf)));
  824. }
  825. /* Callback invoked when a previously prepared write is to be executed */
  826. static void gatts_request_exec_write_cb(int conn_id, int trans_id,
  827. bt_bdaddr_t *bda, int exec_write)
  828. {
  829. char buf[MAX_ADDR_STR_LEN];
  830. haltest_info("%s: conn_id=%d trans_id=%d bda=%s exec_write=%d\n",
  831. __func__, conn_id, trans_id, bt_bdaddr_t2str(bda, buf),
  832. exec_write);
  833. }
  834. /*
  835. * Callback triggered in response to send_response if the remote device
  836. * sends a confirmation.
  837. */
  838. static void gatts_response_confirmation_cb(int status, int handle)
  839. {
  840. haltest_info("%s: status=%d handle=0x%x\n", __func__, status, handle);
  841. }
  842. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  843. /**
  844. * Callback confirming that a notification or indication has been sent
  845. * to a remote device.
  846. */
  847. static void gatts_indication_sent_cb(int conn_id, int status)
  848. {
  849. haltest_info("%s: status=%d conn_id=%d", __func__, status, conn_id);
  850. }
  851. /**
  852. * Callback notifying an application that a remote device connection is
  853. * currently congested and cannot receive any more data. An application
  854. * should avoid sending more data until a further callback is received
  855. * indicating the congestion status has been cleared.
  856. */
  857. static void gatts_congestion_cb(int conn_id, bool congested)
  858. {
  859. haltest_info("%s: conn_id=%d congested=%d", __func__, conn_id,
  860. congested);
  861. }
  862. #endif
  863. static const btgatt_server_callbacks_t btgatt_server_callbacks = {
  864. .register_server_cb = gatts_register_server_cb,
  865. .connection_cb = gatts_connection_cb,
  866. .service_added_cb = gatts_service_added_cb,
  867. .included_service_added_cb = gatts_included_service_added_cb,
  868. .characteristic_added_cb = gatts_characteristic_added_cb,
  869. .descriptor_added_cb = gatts_descriptor_added_cb,
  870. .service_started_cb = gatts_service_started_cb,
  871. .service_stopped_cb = gatts_service_stopped_cb,
  872. .service_deleted_cb = gatts_service_deleted_cb,
  873. .request_read_cb = gatts_request_read_cb,
  874. .request_write_cb = gatts_request_write_cb,
  875. .request_exec_write_cb = gatts_request_exec_write_cb,
  876. .response_confirmation_cb = gatts_response_confirmation_cb,
  877. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  878. .indication_sent_cb = gatts_indication_sent_cb,
  879. .congestion_cb = gatts_congestion_cb,
  880. #endif
  881. };
  882. static const btgatt_callbacks_t gatt_cbacks = {
  883. .size = sizeof(gatt_cbacks),
  884. .client = &btgatt_client_callbacks,
  885. .server = &btgatt_server_callbacks
  886. };
  887. /*
  888. * convert hex string to uint8_t array
  889. */
  890. static int fill_buffer(const char *str, uint8_t *out, int out_size)
  891. {
  892. int str_len;
  893. int i, j;
  894. char c;
  895. uint8_t b;
  896. str_len = strlen(str);
  897. /* Hex string must be byte format */
  898. if (str_len % 2)
  899. return -1;
  900. for (i = 0, j = 0; i < out_size && j < str_len; i++, j++) {
  901. c = str[j];
  902. if (c >= 'a' && c <= 'f')
  903. c += 'A' - 'a';
  904. if (c >= '0' && c <= '9')
  905. b = c - '0';
  906. else if (c >= 'A' && c <= 'F')
  907. b = 10 + c - 'A';
  908. else
  909. return 0;
  910. j++;
  911. c = str[j];
  912. if (c >= 'a' && c <= 'f')
  913. c += 'A' - 'a';
  914. if (c >= '0' && c <= '9')
  915. b = b * 16 + c - '0';
  916. else if (c >= 'A' && c <= 'F')
  917. b = b * 16 + 10 + c - 'A';
  918. else
  919. return 0;
  920. out[i] = b;
  921. }
  922. return i;
  923. }
  924. /* gatt client methods */
  925. /* init */
  926. static void init_p(int argc, const char **argv)
  927. {
  928. RETURN_IF_NULL(if_gatt);
  929. EXEC(if_gatt->init, &gatt_cbacks);
  930. }
  931. /* cleanup */
  932. static void cleanup_p(int argc, const char **argv)
  933. {
  934. RETURN_IF_NULL(if_gatt);
  935. EXECV(if_gatt->cleanup);
  936. if_gatt = NULL;
  937. }
  938. static struct method methods[] = {
  939. STD_METHOD(init),
  940. STD_METHOD(cleanup),
  941. END_METHOD
  942. };
  943. const struct interface gatt_if = {
  944. .name = "gatt",
  945. .methods = methods
  946. };
  947. /* register_client */
  948. static void register_client_p(int argc, const char **argv)
  949. {
  950. bt_uuid_t uuid;
  951. RETURN_IF_NULL(if_gatt);
  952. /* uuid */
  953. if (argc <= 2)
  954. gatt_str2bt_uuid_t("babe4bed", -1, &uuid);
  955. else
  956. gatt_str2bt_uuid_t(argv[2], -1, &uuid);
  957. EXEC(if_gatt->client->register_client, &uuid);
  958. }
  959. /* unregister_client */
  960. static void unregister_client_c(int argc, const char **argv,
  961. enum_func *enum_func, void **user)
  962. {
  963. if (argc == 3) {
  964. *user = client_if_str;
  965. *enum_func = enum_one_string;
  966. }
  967. }
  968. static void unregister_client_p(int argc, const char **argv)
  969. {
  970. int client_if;
  971. RETURN_IF_NULL(if_gatt);
  972. VERIFY_CLIENT_IF(2, client_if);
  973. EXEC(if_gatt->client->unregister_client, client_if);
  974. }
  975. /* scan */
  976. /* Same completion as unregister for now, start stop is not auto completed */
  977. #define scan_c unregister_client_c
  978. static void scan_p(int argc, const char **argv)
  979. {
  980. #if ANDROID_VERSION < PLATFORM_VER(5, 0, 0)
  981. int client_if;
  982. #endif
  983. int start = 1;
  984. RETURN_IF_NULL(if_gatt);
  985. #if ANDROID_VERSION < PLATFORM_VER(5, 0, 0)
  986. VERIFY_CLIENT_IF(2, client_if);
  987. /* start */
  988. if (argc >= 4)
  989. start = strtol(argv[3], NULL, 0);
  990. EXEC(if_gatt->client->scan, client_if, start);
  991. #else
  992. /* start */
  993. if (argc >= 3)
  994. start = strtol(argv[2], NULL, 0);
  995. EXEC(if_gatt->client->scan, start);
  996. #endif
  997. }
  998. /* connect */
  999. static void connect_c(int argc, const char **argv, enum_func *enum_func,
  1000. void **user)
  1001. {
  1002. if (argc == 3) {
  1003. *user = client_if_str;
  1004. *enum_func = enum_one_string;
  1005. } else if (argc == 4) {
  1006. *user = NULL;
  1007. *enum_func = enum_devices;
  1008. }
  1009. }
  1010. static void connect_p(int argc, const char **argv)
  1011. {
  1012. int client_if;
  1013. bt_bdaddr_t bd_addr;
  1014. int is_direct = 1;
  1015. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  1016. int transport = 1;
  1017. #endif
  1018. RETURN_IF_NULL(if_gatt);
  1019. VERIFY_CLIENT_IF(2, client_if);
  1020. VERIFY_ADDR_ARG(3, &bd_addr);
  1021. /* is_direct */
  1022. if (argc > 4)
  1023. is_direct = strtol(argv[4], NULL, 0);
  1024. #if ANDROID_VERSION < PLATFORM_VER(5, 0, 0)
  1025. EXEC(if_gatt->client->connect, client_if, &bd_addr, is_direct);
  1026. #else
  1027. /* transport */
  1028. if (argc > 5)
  1029. transport = strtol(argv[5], NULL, 0);
  1030. EXEC(if_gatt->client->connect, client_if, &bd_addr, is_direct,
  1031. transport);
  1032. #endif
  1033. }
  1034. /* disconnect */
  1035. static void disconnect_c(int argc, const char **argv, enum_func *enum_func,
  1036. void **user)
  1037. {
  1038. if (argc == 3) {
  1039. *user = client_if_str;
  1040. *enum_func = enum_one_string;
  1041. } else if (argc == 4) {
  1042. *user = last_addr;
  1043. *enum_func = enum_one_string;
  1044. } else if (argc == 5) {
  1045. *user = conn_id_str;
  1046. *enum_func = enum_one_string;
  1047. }
  1048. }
  1049. static void disconnect_p(int argc, const char **argv)
  1050. {
  1051. int client_if;
  1052. bt_bdaddr_t bd_addr;
  1053. int conn_id;
  1054. RETURN_IF_NULL(if_gatt);
  1055. VERIFY_CLIENT_IF(2, client_if);
  1056. VERIFY_ADDR_ARG(3, &bd_addr);
  1057. VERIFY_CONN_ID(4, conn_id);
  1058. EXEC(if_gatt->client->disconnect, client_if, &bd_addr, conn_id);
  1059. }
  1060. /* listen */
  1061. /* Same completion as unregister for now, start stop is not auto completed */
  1062. #define listen_c unregister_client_c
  1063. static void listen_p(int argc, const char **argv)
  1064. {
  1065. int client_if;
  1066. int start = 1;
  1067. RETURN_IF_NULL(if_gatt);
  1068. VERIFY_CLIENT_IF(2, client_if);
  1069. /* start */
  1070. if (argc >= 4)
  1071. start = strtol(argv[3], NULL, 0);
  1072. EXEC(if_gatt->client->listen, client_if, start);
  1073. }
  1074. /* refresh */
  1075. static void refresh_c(int argc, const char **argv, enum_func *enum_func,
  1076. void **user)
  1077. {
  1078. if (argc == 3) {
  1079. *user = client_if_str;
  1080. *enum_func = enum_one_string;
  1081. } else if (argc == 4) {
  1082. *enum_func = enum_devices;
  1083. }
  1084. }
  1085. static void refresh_p(int argc, const char **argv)
  1086. {
  1087. int client_if;
  1088. bt_bdaddr_t bd_addr;
  1089. RETURN_IF_NULL(if_gatt);
  1090. VERIFY_CLIENT_IF(2, client_if);
  1091. VERIFY_ADDR_ARG(3, &bd_addr);
  1092. EXEC(if_gatt->client->refresh, client_if, &bd_addr);
  1093. }
  1094. /* search_service */
  1095. static void search_service_c(int argc, const char **argv, enum_func *enum_func,
  1096. void **user)
  1097. {
  1098. if (argc == 3) {
  1099. *user = conn_id_str;
  1100. *enum_func = enum_one_string;
  1101. }
  1102. }
  1103. static void search_service_p(int argc, const char **argv)
  1104. {
  1105. int conn_id;
  1106. RETURN_IF_NULL(if_gatt);
  1107. VERIFY_CONN_ID(2, conn_id);
  1108. /* uuid */
  1109. if (argc <= 3) {
  1110. EXEC(if_gatt->client->search_service, conn_id, NULL);
  1111. } else {
  1112. bt_uuid_t filter_uuid;
  1113. gatt_str2bt_uuid_t(argv[3], -1, &filter_uuid);
  1114. EXEC(if_gatt->client->search_service, conn_id, &filter_uuid);
  1115. }
  1116. }
  1117. /* get_included_service */
  1118. static void get_included_service_c(int argc, const char **argv,
  1119. enum_func *enum_func, void **user)
  1120. {
  1121. if (argc == 3) {
  1122. *user = conn_id_str;
  1123. *enum_func = enum_one_string;
  1124. }
  1125. }
  1126. static void get_included_service_p(int argc, const char **argv)
  1127. {
  1128. int conn_id;
  1129. btgatt_srvc_id_t srvc_id;
  1130. RETURN_IF_NULL(if_gatt);
  1131. VERIFY_CONN_ID(2, conn_id);
  1132. VERIFY_SRVC_ID(3, &srvc_id);
  1133. EXEC(if_gatt->client->get_included_service, conn_id, &srvc_id, NULL);
  1134. }
  1135. /* get_characteristic */
  1136. /* Same completion as get_included_service_c */
  1137. #define get_characteristic_c get_included_service_c
  1138. static void get_characteristic_p(int argc, const char **argv)
  1139. {
  1140. int conn_id;
  1141. btgatt_srvc_id_t srvc_id;
  1142. RETURN_IF_NULL(if_gatt);
  1143. VERIFY_CONN_ID(2, conn_id);
  1144. VERIFY_SRVC_ID(3, &srvc_id);
  1145. EXEC(if_gatt->client->get_characteristic, conn_id, &srvc_id, NULL);
  1146. }
  1147. /* get_descriptor */
  1148. /* Same completion as get_included_service_c */
  1149. #define get_descriptor_c get_included_service_c
  1150. static void get_descriptor_p(int argc, const char **argv)
  1151. {
  1152. int conn_id;
  1153. btgatt_srvc_id_t srvc_id;
  1154. btgatt_gatt_id_t char_id;
  1155. RETURN_IF_NULL(if_gatt);
  1156. VERIFY_CONN_ID(2, conn_id);
  1157. VERIFY_SRVC_ID(3, &srvc_id);
  1158. VERIFY_CHAR_ID(4, &char_id);
  1159. EXEC(if_gatt->client->get_descriptor, conn_id, &srvc_id, &char_id,
  1160. NULL);
  1161. }
  1162. /* read_characteristic */
  1163. /* Same completion as get_included_service_c */
  1164. #define read_characteristic_c get_included_service_c
  1165. static void read_characteristic_p(int argc, const char **argv)
  1166. {
  1167. int conn_id;
  1168. btgatt_srvc_id_t srvc_id;
  1169. btgatt_gatt_id_t char_id;
  1170. int auth_req = 0;
  1171. RETURN_IF_NULL(if_gatt);
  1172. VERIFY_CONN_ID(2, conn_id);
  1173. VERIFY_SRVC_ID(3, &srvc_id);
  1174. VERIFY_CHAR_ID(4, &char_id);
  1175. /* auth_req */
  1176. if (argc > 5)
  1177. auth_req = strtol(argv[5], NULL, 0);
  1178. EXEC(if_gatt->client->read_characteristic, conn_id, &srvc_id, &char_id,
  1179. auth_req);
  1180. }
  1181. /* write_characteristic */
  1182. static void write_characteristic_c(int argc, const char **argv,
  1183. enum_func *enum_func, void **user)
  1184. {
  1185. /*
  1186. * This should be from tGATT_WRITE_TYPE but it's burried
  1187. * inside bluedroid guts
  1188. */
  1189. static const char *wrtypes[] = { "1", "2", "3", NULL };
  1190. if (argc == 3) {
  1191. *user = conn_id_str;
  1192. *enum_func = enum_one_string;
  1193. } else if (argc == 6) {
  1194. *user = wrtypes;
  1195. *enum_func = enum_strings;
  1196. }
  1197. }
  1198. static void write_characteristic_p(int argc, const char **argv)
  1199. {
  1200. int conn_id;
  1201. btgatt_srvc_id_t srvc_id;
  1202. btgatt_gatt_id_t char_id;
  1203. int write_type;
  1204. int len;
  1205. int auth_req = 0;
  1206. uint8_t value[100];
  1207. RETURN_IF_NULL(if_gatt);
  1208. VERIFY_CONN_ID(2, conn_id);
  1209. VERIFY_SRVC_ID(3, &srvc_id);
  1210. VERIFY_CHAR_ID(4, &char_id);
  1211. /* write type */
  1212. if (argc <= 5) {
  1213. haltest_error("No write type specified\n");
  1214. return;
  1215. }
  1216. write_type = strtol(argv[5], NULL, 0);
  1217. GET_VERIFY_HEX_STRING(6, value, len);
  1218. /* auth_req */
  1219. if (argc > 7)
  1220. auth_req = strtol(argv[7], NULL, 0);
  1221. EXEC(if_gatt->client->write_characteristic, conn_id, &srvc_id, &char_id,
  1222. write_type, len, auth_req, (char *) value);
  1223. }
  1224. /* read_descriptor */
  1225. /* Same completion as get_included_service_c */
  1226. #define read_descriptor_c get_included_service_c
  1227. static void read_descriptor_p(int argc, const char **argv)
  1228. {
  1229. int conn_id;
  1230. btgatt_srvc_id_t srvc_id;
  1231. btgatt_gatt_id_t char_id;
  1232. btgatt_descr_id_t descr_id;
  1233. int auth_req = 0;
  1234. RETURN_IF_NULL(if_gatt);
  1235. VERIFY_CONN_ID(2, conn_id);
  1236. VERIFY_SRVC_ID(3, &srvc_id);
  1237. VERIFY_CHAR_ID(4, &char_id);
  1238. VERIFY_DESCR_ID(5, &descr_id);
  1239. /* auth_req */
  1240. if (argc > 6)
  1241. auth_req = strtol(argv[6], NULL, 0);
  1242. EXEC(if_gatt->client->read_descriptor, conn_id, &srvc_id, &char_id,
  1243. &descr_id, auth_req);
  1244. }
  1245. /* write_descriptor */
  1246. static void write_descriptor_c(int argc, const char **argv,
  1247. enum_func *enum_func, void **user)
  1248. {
  1249. /*
  1250. * This should be from tGATT_WRITE_TYPE but it's burried
  1251. * inside bluedroid guts
  1252. */
  1253. static const char *wrtypes[] = { "1", "2", "3", NULL };
  1254. if (argc == 3) {
  1255. *user = conn_id_str;
  1256. *enum_func = enum_one_string;
  1257. } else if (argc == 7) {
  1258. *user = wrtypes;
  1259. *enum_func = enum_strings;
  1260. }
  1261. }
  1262. static void write_descriptor_p(int argc, const char **argv)
  1263. {
  1264. int conn_id;
  1265. btgatt_srvc_id_t srvc_id;
  1266. btgatt_gatt_id_t char_id;
  1267. btgatt_descr_id_t descr_id;
  1268. int write_type;
  1269. int len;
  1270. int auth_req = 0;
  1271. uint8_t value[200] = {0};
  1272. RETURN_IF_NULL(if_gatt);
  1273. VERIFY_CONN_ID(2, conn_id);
  1274. VERIFY_SRVC_ID(3, &srvc_id);
  1275. VERIFY_CHAR_ID(4, &char_id);
  1276. VERIFY_DESCR_ID(5, &descr_id);
  1277. /* write type */
  1278. if (argc <= 6) {
  1279. haltest_error("No write type specified\n");
  1280. return;
  1281. }
  1282. write_type = strtol(argv[6], NULL, 0);
  1283. /* value */
  1284. if (argc <= 7) {
  1285. haltest_error("No value specified\n");
  1286. return;
  1287. }
  1288. /* len in chars */
  1289. if (strncmp(argv[7], "0X", 2) && strncmp(argv[7], "0x", 2)) {
  1290. haltest_error("Value must be hex string");
  1291. return;
  1292. }
  1293. len = fill_buffer(argv[7] + 2, value, sizeof(value));
  1294. /* auth_req */
  1295. if (argc > 8)
  1296. auth_req = strtol(argv[8], NULL, 0);
  1297. EXEC(if_gatt->client->write_descriptor, conn_id, &srvc_id, &char_id,
  1298. &descr_id, write_type, len, auth_req, (char *) value);
  1299. }
  1300. /* execute_write */
  1301. /* Same completion as search_service */
  1302. #define execute_write_c search_service_c
  1303. static void execute_write_p(int argc, const char **argv)
  1304. {
  1305. int conn_id;
  1306. int execute;
  1307. RETURN_IF_NULL(if_gatt);
  1308. VERIFY_CONN_ID(2, conn_id);
  1309. /* execute */
  1310. if (argc <= 3) {
  1311. haltest_error("No execute specified\n");
  1312. return;
  1313. }
  1314. execute = strtol(argv[3], NULL, 0);
  1315. EXEC(if_gatt->client->execute_write, conn_id, execute);
  1316. }
  1317. /* register_for_notification */
  1318. static void register_for_notification_c(int argc, const char **argv,
  1319. enum_func *enum_func, void **user)
  1320. {
  1321. if (argc == 3) {
  1322. *user = client_if_str;
  1323. *enum_func = enum_one_string;
  1324. } else if (argc == 4) {
  1325. *user = last_addr;
  1326. *enum_func = enum_one_string;
  1327. }
  1328. }
  1329. static void register_for_notification_p(int argc, const char **argv)
  1330. {
  1331. int client_if;
  1332. bt_bdaddr_t bd_addr;
  1333. btgatt_srvc_id_t srvc_id;
  1334. btgatt_gatt_id_t char_id;
  1335. RETURN_IF_NULL(if_gatt);
  1336. VERIFY_CLIENT_IF(2, client_if);
  1337. VERIFY_ADDR_ARG(3, &bd_addr);
  1338. VERIFY_SRVC_ID(4, &srvc_id);
  1339. VERIFY_CHAR_ID(5, &char_id);
  1340. EXEC(if_gatt->client->register_for_notification, client_if, &bd_addr,
  1341. &srvc_id, &char_id);
  1342. }
  1343. /* deregister_for_notification */
  1344. /* Same completion as search_service */
  1345. #define deregister_for_notification_c register_for_notification_c
  1346. static void deregister_for_notification_p(int argc, const char **argv)
  1347. {
  1348. int client_if;
  1349. bt_bdaddr_t bd_addr;
  1350. btgatt_srvc_id_t srvc_id;
  1351. btgatt_gatt_id_t char_id;
  1352. RETURN_IF_NULL(if_gatt);
  1353. VERIFY_CLIENT_IF(2, client_if);
  1354. VERIFY_ADDR_ARG(3, &bd_addr);
  1355. VERIFY_SRVC_ID(4, &srvc_id);
  1356. VERIFY_CHAR_ID(5, &char_id);
  1357. EXEC(if_gatt->client->deregister_for_notification, client_if, &bd_addr,
  1358. &srvc_id, &char_id);
  1359. }
  1360. /* read_remote_rssi */
  1361. static void read_remote_rssi_c(int argc, const char **argv,
  1362. enum_func *enum_func, void **user)
  1363. {
  1364. if (argc == 3) {
  1365. *user = client_if_str;
  1366. *enum_func = enum_one_string;
  1367. } else if (argc == 4) {
  1368. *enum_func = enum_devices;
  1369. }
  1370. }
  1371. static void read_remote_rssi_p(int argc, const char **argv)
  1372. {
  1373. int client_if;
  1374. bt_bdaddr_t bd_addr;
  1375. RETURN_IF_NULL(if_gatt);
  1376. VERIFY_CLIENT_IF(2, client_if);
  1377. VERIFY_ADDR_ARG(3, &bd_addr);
  1378. EXEC(if_gatt->client->read_remote_rssi, client_if, &bd_addr);
  1379. }
  1380. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  1381. /* scan filter parameter setup */
  1382. static void scan_filter_param_setup_c(int argc, const char **argv,
  1383. enum_func *enum_func, void **user)
  1384. {
  1385. if (argc == 2) {
  1386. *user = client_if_str;
  1387. *enum_func = enum_one_string;
  1388. }
  1389. }
  1390. static void scan_filter_param_setup_p(int argc, const char **argv)
  1391. {
  1392. int client_if;
  1393. int action;
  1394. int filt_index;
  1395. int feat_seln;
  1396. int list_logic_type, filt_logic_type;
  1397. int rssi_high_thres, rssi_low_thres;
  1398. int dely_mode;
  1399. int found_timeout, lost_timeout, found_timeout_cnt;
  1400. RETURN_IF_NULL(if_gatt);
  1401. VERIFY_CLIENT_IF(2, client_if);
  1402. VERIFY_ACTION(3, action);
  1403. VERIFY_FILT_INDEX(4, filt_index);
  1404. VERIFY_FEAT_SELN(5, feat_seln);
  1405. VERIFY_LIST_LOGIC_TYPE(6, list_logic_type);
  1406. VERIFY_FILT_LOGIC_TYPE(7, filt_logic_type);
  1407. VERIFY_RSSI_HI_THR(8, rssi_high_thres);
  1408. VERIFY_RSSI_LOW_THR(9, rssi_low_thres);
  1409. VERIFY_DELY_MODE(10, dely_mode);
  1410. VERIFY_FND_TIME(11, found_timeout);
  1411. VERIFY_LOST_TIME(12, lost_timeout);
  1412. VERIFY_FND_TIME_CNT(13, found_timeout_cnt);
  1413. EXEC(if_gatt->client->scan_filter_param_setup, client_if, action,
  1414. filt_index, feat_seln, list_logic_type, filt_logic_type,
  1415. rssi_high_thres, rssi_low_thres, dely_mode, found_timeout,
  1416. lost_timeout, found_timeout_cnt);
  1417. }
  1418. /* scan filter add remove */
  1419. static void scan_filter_add_remove_c(int argc, const char **argv,
  1420. enum_func *enum_func, void **user)
  1421. {
  1422. if (argc == 2) {
  1423. *user = client_if_str;
  1424. *enum_func = enum_one_string;
  1425. } else if (argc == 10) {
  1426. *user = last_addr;
  1427. *enum_func = enum_one_string;
  1428. }
  1429. }
  1430. static void scan_filter_add_remove_p(int argc, const char **argv)
  1431. {
  1432. int client_if;
  1433. int action;
  1434. int filt_type;
  1435. int filt_index;
  1436. int company_id;
  1437. int company_id_mask;
  1438. bt_uuid_t p_uuid;
  1439. bt_uuid_t p_uuid_mask;
  1440. bt_bdaddr_t bd_addr;
  1441. char addr_type;
  1442. int data_len;
  1443. uint8_t p_data[100];
  1444. int mask_len;
  1445. uint8_t p_mask[100];
  1446. RETURN_IF_NULL(if_gatt);
  1447. VERIFY_CLIENT_IF(2, client_if);
  1448. VERIFY_ACTION(3, action);
  1449. VERIFY_FILT_TYPE(4, filt_type);
  1450. VERIFY_FILT_INDEX(5, filt_index);
  1451. VERIFY_COMP_ID(6, company_id);
  1452. VERIFY_COMP_ID_MASK(7, company_id_mask);
  1453. if (argc <= 9) {
  1454. haltest_error("No p_uuid, p_uuid_mask specified\n");
  1455. return;
  1456. }
  1457. gatt_str2bt_uuid_t(argv[8], -1, &p_uuid);
  1458. gatt_str2bt_uuid_t(argv[9], -1, &p_uuid_mask);
  1459. VERIFY_UUID(8, &p_uuid);
  1460. VERIFY_UUID(9, &p_uuid_mask);
  1461. VERIFY_ADDR_ARG(10, &bd_addr);
  1462. VERIFY_ADDR_TYPE(11, addr_type);
  1463. GET_VERIFY_HEX_STRING(12, p_data, data_len);
  1464. GET_VERIFY_HEX_STRING(13, p_mask, mask_len);
  1465. EXEC(if_gatt->client->scan_filter_add_remove, client_if, action,
  1466. filt_type, filt_index, company_id, company_id_mask,
  1467. &p_uuid, &p_uuid_mask, &bd_addr, addr_type, data_len,
  1468. (char *) p_data, mask_len, (char *) p_mask);
  1469. }
  1470. /* scan filter clean */
  1471. static void scan_filter_clear_c(int argc, const char **argv,
  1472. enum_func *enum_func, void **user)
  1473. {
  1474. if (argc == 2) {
  1475. *user = client_if_str;
  1476. *enum_func = enum_one_string;
  1477. }
  1478. }
  1479. static void scan_filter_clear_p(int argc, const char **argv)
  1480. {
  1481. int client_if;
  1482. int filt_index;
  1483. RETURN_IF_NULL(if_gatt);
  1484. VERIFY_CLIENT_IF(2, client_if);
  1485. VERIFY_FILT_INDEX(3, filt_index);
  1486. EXEC(if_gatt->client->scan_filter_clear, client_if, filt_index);
  1487. }
  1488. /* scan filter enable */
  1489. static void scan_filter_enable_c(int argc, const char **argv,
  1490. enum_func *enum_func, void **user)
  1491. {
  1492. if (argc == 2) {
  1493. *user = client_if_str;
  1494. *enum_func = enum_one_string;
  1495. }
  1496. }
  1497. static void scan_filter_enable_p(int argc, const char **argv)
  1498. {
  1499. int client_if;
  1500. int enable = 0;
  1501. RETURN_IF_NULL(if_gatt);
  1502. VERIFY_CLIENT_IF(2, client_if);
  1503. /* enable */
  1504. if (argc >= 4)
  1505. enable = strtol(argv[3], NULL, 0);
  1506. EXEC(if_gatt->client->scan_filter_clear, client_if, enable);
  1507. }
  1508. /* set advertising data */
  1509. static void set_adv_data_c(int argc, const char **argv,
  1510. enum_func *enum_func, void **user)
  1511. {
  1512. if (argc == 2) {
  1513. *user = client_if_str;
  1514. *enum_func = enum_one_string;
  1515. }
  1516. }
  1517. static void set_adv_data_p(int argc, const char **argv)
  1518. {
  1519. int client_if;
  1520. bool set_scan_rsp = false;
  1521. bool include_name = false;
  1522. bool include_txpower = false;
  1523. int min_interval, max_interval;
  1524. int appearance;
  1525. uint16_t manufacturer_len;
  1526. uint8_t manufacturer_data[100];
  1527. uint16_t service_data_len;
  1528. uint8_t service_data[100];
  1529. uint16_t service_uuid_len;
  1530. uint8_t service_uuid[100];
  1531. RETURN_IF_NULL(if_gatt);
  1532. VERIFY_CLIENT_IF(2, client_if);
  1533. /* set scan response */
  1534. if (argc >= 4)
  1535. set_scan_rsp = strtol(argv[3], NULL, 0);
  1536. /* include name */
  1537. if (argc >= 5)
  1538. include_name = strtol(argv[4], NULL, 0);
  1539. /* include txpower */
  1540. if (argc >= 6)
  1541. include_txpower = strtol(argv[5], NULL, 0);
  1542. VERIFY_MIN_INTERVAL(6, min_interval);
  1543. VERIFY_MAX_INTERVAL(7, max_interval);
  1544. VERIFY_APPEARANCE(8, appearance);
  1545. GET_VERIFY_HEX_STRING(9, manufacturer_data, manufacturer_len);
  1546. GET_VERIFY_HEX_STRING(10, service_data, service_data_len);
  1547. GET_VERIFY_HEX_STRING(11, service_uuid, service_uuid_len);
  1548. EXEC(if_gatt->client->set_adv_data, client_if, set_scan_rsp,
  1549. include_name, include_txpower, min_interval, max_interval,
  1550. appearance, manufacturer_len, (char *) manufacturer_data,
  1551. service_data_len, (char *) service_data, service_uuid_len,
  1552. (char *) service_uuid);
  1553. }
  1554. /* configure mtu */
  1555. static void configure_mtu_c(int argc, const char **argv,
  1556. enum_func *enum_func, void **user)
  1557. {
  1558. if (argc == 2) {
  1559. *user = conn_id_str;
  1560. *enum_func = enum_one_string;
  1561. }
  1562. }
  1563. static void configure_mtu_p(int argc, const char **argv)
  1564. {
  1565. int conn_id;
  1566. int mtu;
  1567. RETURN_IF_NULL(if_gatt);
  1568. VERIFY_CONN_ID(2, conn_id);
  1569. VERIFY_MTU(3, mtu);
  1570. EXEC(if_gatt->client->configure_mtu, conn_id, mtu);
  1571. }
  1572. /* con parameter update */
  1573. static void conn_parameter_update_c(int argc, const char **argv,
  1574. enum_func *enum_func, void **user)
  1575. {
  1576. if (argc == 2) {
  1577. *user = last_addr;
  1578. *enum_func = enum_one_string;
  1579. }
  1580. }
  1581. static void conn_parameter_update_p(int argc, const char **argv)
  1582. {
  1583. bt_bdaddr_t bd_addr;
  1584. int min_interval, max_interval;
  1585. int latency;
  1586. int timeout;
  1587. RETURN_IF_NULL(if_gatt);
  1588. VERIFY_ADDR_ARG(2, &bd_addr);
  1589. VERIFY_MIN_INTERVAL(3, min_interval);
  1590. VERIFY_MAX_INTERVAL(4, max_interval);
  1591. VERIFY_LATENCY(5, latency);
  1592. VERIFY_TIMEOUT(6, timeout);
  1593. EXEC(if_gatt->client->conn_parameter_update, &bd_addr, min_interval,
  1594. max_interval, latency, timeout);
  1595. }
  1596. /* set scan parameters */
  1597. static void set_scan_parameters_p(int argc, const char **argv)
  1598. {
  1599. int scan_interval;
  1600. int scan_window;
  1601. RETURN_IF_NULL(if_gatt);
  1602. VERIFY_SCAN_INTERVAL(2, scan_interval);
  1603. VERIFY_SCAN_WINDOW(3, scan_window);
  1604. EXEC(if_gatt->client->set_scan_parameters, scan_interval, scan_window);
  1605. }
  1606. /* enable multi advertising */
  1607. static void multi_adv_enable_c(int argc, const char **argv,
  1608. enum_func *enum_func, void **user)
  1609. {
  1610. if (argc == 2) {
  1611. *user = client_if_str;
  1612. *enum_func = enum_one_string;
  1613. }
  1614. }
  1615. static void multi_adv_enable_p(int argc, const char **argv)
  1616. {
  1617. int client_if;
  1618. int min_interval, max_interval;
  1619. int adv_type;
  1620. int chnl_map;
  1621. int tx_power;
  1622. int timeout_s;
  1623. RETURN_IF_NULL(if_gatt);
  1624. VERIFY_CLIENT_IF(2, client_if);
  1625. VERIFY_MIN_INTERVAL(3, min_interval);
  1626. VERIFY_MAX_INTERVAL(4, max_interval);
  1627. VERIFY_ADV_TYPE(5, adv_type);
  1628. VERIFY_CHNL_MAP(6, chnl_map);
  1629. VERIFY_TX_POWER(7, tx_power);
  1630. VERIFY_TIMEOUT_S(8, timeout_s);
  1631. EXEC(if_gatt->client->multi_adv_enable, client_if, min_interval,
  1632. max_interval, adv_type, chnl_map, tx_power, timeout_s);
  1633. }
  1634. /* update multi advertiser */
  1635. static void multi_adv_update_c(int argc, const char **argv,
  1636. enum_func *enum_func, void **user)
  1637. {
  1638. if (argc == 2) {
  1639. *user = client_if_str;
  1640. *enum_func = enum_one_string;
  1641. }
  1642. }
  1643. static void multi_adv_update_p(int argc, const char **argv)
  1644. {
  1645. int client_if;
  1646. int min_interval, max_interval;
  1647. int adv_type;
  1648. int chnl_map;
  1649. int tx_power;
  1650. int timeout_s;
  1651. RETURN_IF_NULL(if_gatt);
  1652. VERIFY_CLIENT_IF(2, client_if);
  1653. VERIFY_MIN_INTERVAL(3, min_interval);
  1654. VERIFY_MAX_INTERVAL(4, max_interval);
  1655. VERIFY_ADV_TYPE(5, adv_type);
  1656. VERIFY_CHNL_MAP(6, chnl_map);
  1657. VERIFY_TX_POWER(7, tx_power);
  1658. VERIFY_TIMEOUT_S(8, timeout_s);
  1659. EXEC(if_gatt->client->multi_adv_update, client_if, min_interval,
  1660. max_interval, adv_type, chnl_map, tx_power, timeout_s);
  1661. }
  1662. /* set advertising data */
  1663. static void multi_adv_set_inst_data_c(int argc, const char **argv,
  1664. enum_func *enum_func, void **user)
  1665. {
  1666. if (argc == 2) {
  1667. *user = client_if_str;
  1668. *enum_func = enum_one_string;
  1669. }
  1670. }
  1671. static void multi_adv_set_inst_data_p(int argc, const char **argv)
  1672. {
  1673. int client_if;
  1674. bool set_scan_rsp = false;
  1675. bool include_name = false;
  1676. bool include_txpower = false;
  1677. int appearance;
  1678. uint16_t manufacturer_len;
  1679. uint8_t manufacturer_data[100];
  1680. uint16_t service_data_len;
  1681. uint8_t service_data[100];
  1682. uint16_t service_uuid_len;
  1683. uint8_t service_uuid[100];
  1684. RETURN_IF_NULL(if_gatt);
  1685. VERIFY_CLIENT_IF(2, client_if);
  1686. /* set scan response */
  1687. if (argc >= 4)
  1688. set_scan_rsp = strtol(argv[3], NULL, 0);
  1689. /* include name */
  1690. if (argc >= 5)
  1691. include_name = strtol(argv[4], NULL, 0);
  1692. /* include txpower */
  1693. if (argc >= 6)
  1694. include_txpower = strtol(argv[5], NULL, 0);
  1695. VERIFY_APPEARANCE(6, appearance);
  1696. GET_VERIFY_HEX_STRING(7, manufacturer_data, manufacturer_len);
  1697. GET_VERIFY_HEX_STRING(8, service_data, service_data_len);
  1698. GET_VERIFY_HEX_STRING(9, service_uuid, service_uuid_len);
  1699. EXEC(if_gatt->client->multi_adv_set_inst_data, client_if, set_scan_rsp,
  1700. include_name, include_txpower, appearance, manufacturer_len,
  1701. (char *) manufacturer_data, service_data_len,
  1702. (char *) service_data, service_uuid_len, (char *) service_uuid);
  1703. }
  1704. /* multi advertising disable */
  1705. static void multi_adv_disable_c(int argc, const char **argv,
  1706. enum_func *enum_func, void **user)
  1707. {
  1708. if (argc == 2) {
  1709. *user = client_if_str;
  1710. *enum_func = enum_one_string;
  1711. }
  1712. }
  1713. static void multi_adv_disable_p(int argc, const char **argv)
  1714. {
  1715. int client_if;
  1716. RETURN_IF_NULL(if_gatt);
  1717. VERIFY_CLIENT_IF(2, client_if);
  1718. EXEC(if_gatt->client->multi_adv_disable, client_if);
  1719. }
  1720. /* batch scanconfigure storage */
  1721. static void batchscan_cfg_storage_c(int argc, const char **argv,
  1722. enum_func *enum_func, void **user)
  1723. {
  1724. if (argc == 2) {
  1725. *user = client_if_str;
  1726. *enum_func = enum_one_string;
  1727. }
  1728. }
  1729. static void batchscan_cfg_storage_p(int argc, const char **argv)
  1730. {
  1731. int client_if;
  1732. int batch_scan_full_max;
  1733. int batch_scan_trunc_max;
  1734. int batch_scan_notify_threshold;
  1735. RETURN_IF_NULL(if_gatt);
  1736. VERIFY_CLIENT_IF(2, client_if);
  1737. VERIFY_BATCH_SCAN_FULL_MAX(3, batch_scan_full_max);
  1738. VERIFY_BATCH_SCAN_TRUNC_MAX(4, batch_scan_trunc_max);
  1739. VERIFY_BATCH_SCAN_NOTIFY_THR(5, batch_scan_notify_threshold);
  1740. EXEC(if_gatt->client->batchscan_cfg_storage, client_if,
  1741. batch_scan_full_max, batch_scan_trunc_max,
  1742. batch_scan_notify_threshold);
  1743. }
  1744. /* enable batch scan */
  1745. static void batchscan_enb_batch_scan_c(int argc, const char **argv,
  1746. enum_func *enum_func, void **user)
  1747. {
  1748. if (argc == 2) {
  1749. *user = client_if_str;
  1750. *enum_func = enum_one_string;
  1751. }
  1752. }
  1753. static void batchscan_enb_batch_scan_p(int argc, const char **argv)
  1754. {
  1755. int client_if;
  1756. int scan_mode, scan_interval, scan_window;
  1757. int addr_type;
  1758. int discard_rule;
  1759. RETURN_IF_NULL(if_gatt);
  1760. VERIFY_CLIENT_IF(2, client_if);
  1761. VERIFY_SCAN_MODE(3, scan_mode);
  1762. VERIFY_SCAN_INTERVAL(4, scan_interval);
  1763. VERIFY_SCAN_WINDOW(5, scan_window);
  1764. VERIFY_ADDR_TYPE(6, addr_type);
  1765. VERIFY_DISCARD_RULE(7, discard_rule);
  1766. EXEC(if_gatt->client->batchscan_enb_batch_scan, client_if, scan_mode,
  1767. scan_interval, scan_window, addr_type, discard_rule);
  1768. }
  1769. /* batchscan disable */
  1770. static void batchscan_dis_batch_scan_c(int argc, const char **argv,
  1771. enum_func *enum_func, void **user)
  1772. {
  1773. if (argc == 2) {
  1774. *user = client_if_str;
  1775. *enum_func = enum_one_string;
  1776. }
  1777. }
  1778. static void batchscan_dis_batch_scan_p(int argc, const char **argv)
  1779. {
  1780. int client_if;
  1781. RETURN_IF_NULL(if_gatt);
  1782. VERIFY_CLIENT_IF(2, client_if);
  1783. EXEC(if_gatt->client->batchscan_dis_batch_scan, client_if);
  1784. }
  1785. /* batchscan read reports */
  1786. static void batchscan_read_reports_c(int argc, const char **argv,
  1787. enum_func *enum_func, void **user)
  1788. {
  1789. if (argc == 2) {
  1790. *user = client_if_str;
  1791. *enum_func = enum_one_string;
  1792. }
  1793. }
  1794. static void batchscan_read_reports_p(int argc, const char **argv)
  1795. {
  1796. int client_if;
  1797. int scan_mode;
  1798. RETURN_IF_NULL(if_gatt);
  1799. VERIFY_CLIENT_IF(2, client_if);
  1800. VERIFY_SCAN_MODE(3, scan_mode);
  1801. EXEC(if_gatt->client->batchscan_read_reports, client_if, scan_mode);
  1802. }
  1803. #endif
  1804. /* get_device_type */
  1805. static void get_device_type_c(int argc, const char **argv, enum_func *enum_func,
  1806. void **user)
  1807. {
  1808. if (argc == 3)
  1809. *enum_func = enum_devices;
  1810. }
  1811. static void get_device_type_p(int argc, const char **argv)
  1812. {
  1813. bt_bdaddr_t bd_addr;
  1814. int dev_type;
  1815. RETURN_IF_NULL(if_gatt);
  1816. VERIFY_ADDR_ARG(2, &bd_addr);
  1817. dev_type = if_gatt->client->get_device_type(&bd_addr);
  1818. haltest_info("%s: %d\n", "get_device_type", dev_type);
  1819. }
  1820. /* test_command */
  1821. static void test_command_c(int argc, const char **argv, enum_func *enum_func,
  1822. void **user)
  1823. {
  1824. if (argc == 4)
  1825. *enum_func = enum_devices;
  1826. }
  1827. static void test_command_p(int argc, const char **argv)
  1828. {
  1829. int command;
  1830. int i;
  1831. bt_bdaddr_t bd_addr;
  1832. bt_uuid_t uuid;
  1833. btgatt_test_params_t params = {
  1834. .bda1 = &bd_addr,
  1835. .uuid1 = &uuid
  1836. };
  1837. uint16_t *u = &params.u1;
  1838. RETURN_IF_NULL(if_gatt);
  1839. /* command */
  1840. if (argc <= 2) {
  1841. haltest_error("No command specified\n");
  1842. return;
  1843. }
  1844. command = strtol(argv[2], NULL, 0);
  1845. VERIFY_ADDR_ARG(3, &bd_addr);
  1846. VERIFY_UUID(4, &uuid);
  1847. for (i = 5; i < argc; i++)
  1848. VERIFY_TEST_ARG(i, *u++);
  1849. EXEC(if_gatt->client->test_command, command, &params);
  1850. }
  1851. static struct method client_methods[] = {
  1852. STD_METHODH(register_client, "[<uuid>]"),
  1853. STD_METHODCH(unregister_client, "<client_if>"),
  1854. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  1855. STD_METHODCH(scan, "[1|0]"),
  1856. STD_METHODCH(connect, "<client_if> <addr> [<is_direct>] [<transport]"),
  1857. STD_METHODCH(scan_filter_param_setup, "<client_if> <action>"
  1858. " <filt_index> <feat_seln> <list_logic_type>"
  1859. " <filt_logic_type> <rssi_high_thres> <rssi_low_thres>"
  1860. " <dely_mode> <found_timeout> <lost_timeout>"
  1861. " <found_timeout_cnt>"),
  1862. STD_METHODCH(scan_filter_add_remove, "<client_if> <action> <filt_type>"
  1863. " <filt_index> <company_id> <company_id_mask>"
  1864. " [<p_uuid>] <p_uuid_mask> <addr> <addr_type>"
  1865. " [<p_data>] [<p_mask>]"),
  1866. STD_METHODCH(scan_filter_clear, "<client_if> <filt_index>"),
  1867. STD_METHODCH(scan_filter_enable, "<client_if> [<enable>]"),
  1868. STD_METHODCH(set_adv_data, "<client_if> [<set_scan_rsp>] <include_name>"
  1869. " [<include_txpower>] <min_interval> <max_interval>"
  1870. " <appearance> [<manufacturer_data>] [<service_data>]"
  1871. " [<service_uuid>]"),
  1872. STD_METHODCH(configure_mtu, "<conn_id> <mtu>"),
  1873. STD_METHODCH(conn_parameter_update, "<bd_addr> <min_interval>"
  1874. " <max_interval> <latency> <timeout>"),
  1875. STD_METHODH(set_scan_parameters, "<scan_inverval> <scan_window>"),
  1876. STD_METHODCH(multi_adv_enable, "<client_if> <min_interval>"
  1877. " <max_interval> <adv_type> <chnl_map> <tx_power>"
  1878. " <timeout_s>"),
  1879. STD_METHODCH(multi_adv_update, "<client_if> <min_interval>"
  1880. " <max_interval> <adv_type> <chnl_map> <tx_power>"
  1881. " <timeout_s>"),
  1882. STD_METHODCH(multi_adv_set_inst_data, "<client_if> [<set_scan_rsp>]"
  1883. " <include_name> [<include_txpower>] <appearance>"
  1884. " [<manufacturer_data>] [<service_data>]"
  1885. " [<service_uuid>]"),
  1886. STD_METHODCH(multi_adv_disable, "<client_if>"),
  1887. STD_METHODCH(batchscan_cfg_storage, "<client_if> <batch_scan_full_max>"
  1888. " <batch_scan_trunc_max>"
  1889. " <batch_scan_notify_threshold>"),
  1890. STD_METHODCH(batchscan_enb_batch_scan, "<client_if> <scan_mode>"
  1891. " <scan_interval> <scan_window> <addr_type>"
  1892. " <discard_rule>"),
  1893. STD_METHODCH(batchscan_dis_batch_scan, "<client_if>"),
  1894. STD_METHODCH(batchscan_read_reports, "<client_if> <scan_mode>"),
  1895. #else
  1896. STD_METHODCH(scan, "<client_if> [1|0]"),
  1897. STD_METHODCH(connect, "<client_if> <addr> [<is_direct>]"),
  1898. #endif
  1899. STD_METHODCH(disconnect, "<client_if> <addr> <conn_id>"),
  1900. STD_METHODCH(refresh, "<client_if> <addr>"),
  1901. STD_METHODCH(search_service, "<conn_id> [<uuid>]"),
  1902. STD_METHODCH(get_included_service, "<conn_id> <srvc_id>"),
  1903. STD_METHODCH(get_characteristic, "<conn_id> <srvc_id>"),
  1904. STD_METHODCH(get_descriptor, "<conn_id> <srvc_id> <char_id>"),
  1905. STD_METHODCH(read_characteristic,
  1906. "<conn_id> <srvc_id> <char_id> [<auth_req>]"),
  1907. STD_METHODCH(write_characteristic,
  1908. "<conn_id> <srvc_id> <char_id> <write_type> <hex_value> [<auth_req>]"),
  1909. STD_METHODCH(read_descriptor,
  1910. "<conn_id> <srvc_id> <char_id> <descr_id> [<auth_req>]"),
  1911. STD_METHODCH(write_descriptor,
  1912. "<conn_id> <srvc_id> <char_id> <descr_id> <write_type> <hex_value> [<auth_req>]"),
  1913. STD_METHODCH(execute_write, "<conn_id> <execute>"),
  1914. STD_METHODCH(register_for_notification,
  1915. "<client_if> <addr> <srvc_id> <char_id>"),
  1916. STD_METHODCH(deregister_for_notification,
  1917. "<client_if> <addr> <srvc_id> <char_id>"),
  1918. STD_METHODCH(read_remote_rssi, "<client_if> <addr>"),
  1919. STD_METHODCH(get_device_type, "<addr>"),
  1920. STD_METHODCH(test_command,
  1921. "<cmd> <addr> <uuid> [u1] [u2] [u3] [u4] [u5]"),
  1922. STD_METHODCH(listen, "<client_if> [1|0]"),
  1923. END_METHOD
  1924. };
  1925. const struct interface gatt_client_if = {
  1926. .name = "gattc",
  1927. .methods = client_methods
  1928. };
  1929. /* gatt server methods */
  1930. /* register_server */
  1931. static void gatts_register_server_p(int argc, const char *argv[])
  1932. {
  1933. bt_uuid_t uuid;
  1934. RETURN_IF_NULL(if_gatt);
  1935. /* uuid */
  1936. if (argc <= 2)
  1937. gatt_str2bt_uuid_t("bed4babe", -1, &uuid);
  1938. else
  1939. gatt_str2bt_uuid_t(argv[2], -1, &uuid);
  1940. EXEC(if_gatt->server->register_server, &uuid);
  1941. }
  1942. /* unregister_server */
  1943. static void gatts_unregister_server_c(int argc, const char **argv,
  1944. enum_func *enum_func, void **user)
  1945. {
  1946. if (argc == 3) {
  1947. *user = server_if_str;
  1948. *enum_func = enum_one_string;
  1949. }
  1950. }
  1951. static void gatts_unregister_server_p(int argc, const char *argv[])
  1952. {
  1953. int server_if;
  1954. RETURN_IF_NULL(if_gatt);
  1955. VERIFY_SERVER_IF(2, server_if);
  1956. EXEC(if_gatt->server->unregister_server, server_if);
  1957. }
  1958. /* connect */
  1959. static void gatts_connect_c(int argc, const char **argv, enum_func *enum_func,
  1960. void **user)
  1961. {
  1962. if (argc == 3) {
  1963. *user = server_if_str;
  1964. *enum_func = enum_one_string;
  1965. } else if (argc == 4) {
  1966. *user = NULL;
  1967. *enum_func = enum_devices;
  1968. }
  1969. }
  1970. static void gatts_connect_p(int argc, const char *argv[])
  1971. {
  1972. int server_if;
  1973. bt_bdaddr_t bd_addr;
  1974. int is_direct = 1;
  1975. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  1976. int transport = 1;
  1977. #endif
  1978. RETURN_IF_NULL(if_gatt);
  1979. VERIFY_SERVER_IF(2, server_if);
  1980. VERIFY_ADDR_ARG(3, &bd_addr);
  1981. /* is_direct */
  1982. if (argc > 4)
  1983. is_direct = strtol(argv[4], NULL, 0);
  1984. #if ANDROID_VERSION < PLATFORM_VER(5, 0, 0)
  1985. EXEC(if_gatt->server->connect, server_if, &bd_addr, is_direct);
  1986. #else
  1987. /* transport */
  1988. if (argc > 5)
  1989. transport = strtol(argv[5], NULL, 0);
  1990. EXEC(if_gatt->server->connect, server_if, &bd_addr, is_direct,
  1991. transport);
  1992. #endif
  1993. }
  1994. /* disconnect */
  1995. static void gatts_disconnect_c(int argc, const char **argv,
  1996. enum_func *enum_func, void **user)
  1997. {
  1998. if (argc == 3) {
  1999. *user = server_if_str;
  2000. *enum_func = enum_one_string;
  2001. } else if (argc == 4) {
  2002. *user = last_addr;
  2003. *enum_func = enum_one_string;
  2004. } else if (argc == 5) {
  2005. *user = conn_id_str;
  2006. *enum_func = enum_one_string;
  2007. }
  2008. }
  2009. static void gatts_disconnect_p(int argc, const char *argv[])
  2010. {
  2011. int server_if;
  2012. bt_bdaddr_t bd_addr;
  2013. int conn_id;
  2014. RETURN_IF_NULL(if_gatt);
  2015. VERIFY_SERVER_IF(2, server_if);
  2016. VERIFY_ADDR_ARG(3, &bd_addr);
  2017. VERIFY_CONN_ID(4, conn_id);
  2018. EXEC(if_gatt->server->disconnect, server_if, &bd_addr, conn_id);
  2019. }
  2020. /* add_service */
  2021. /* Same completion as gatts_unregister_server_c */
  2022. #define gatts_add_service_c gatts_unregister_server_c
  2023. static void gatts_add_service_p(int argc, const char *argv[])
  2024. {
  2025. int server_if;
  2026. btgatt_srvc_id_t srvc_id;
  2027. int num_handles;
  2028. RETURN_IF_NULL(if_gatt);
  2029. VERIFY_SERVER_IF(2, server_if);
  2030. VERIFY_SRVC_ID(3, &srvc_id);
  2031. /* num handles */
  2032. if (argc <= 4) {
  2033. haltest_error("No num_handles specified\n");
  2034. return;
  2035. }
  2036. num_handles = strtol(argv[4], NULL, 0);
  2037. EXEC(if_gatt->server->add_service, server_if, &srvc_id, num_handles);
  2038. }
  2039. /* add_included_service */
  2040. /* Same completion as gatts_unregister_server_c */
  2041. #define gatts_add_included_service_c gatts_unregister_server_c
  2042. static void gatts_add_included_service_p(int argc, const char *argv[])
  2043. {
  2044. int server_if;
  2045. int service_handle;
  2046. int included_handle;
  2047. RETURN_IF_NULL(if_gatt);
  2048. VERIFY_SERVER_IF(2, server_if);
  2049. VERIFY_SERVICE_HANDLE(3, service_handle);
  2050. VERIFY_HANDLE(4, included_handle);
  2051. EXEC(if_gatt->server->add_included_service, server_if, service_handle,
  2052. included_handle);
  2053. }
  2054. /* add_characteristic */
  2055. /* Same completion as gatts_unregister_server_c */
  2056. #define gatts_add_characteristic_c gatts_unregister_server_c
  2057. static void gatts_add_characteristic_p(int argc, const char *argv[])
  2058. {
  2059. int server_if;
  2060. int service_handle;
  2061. int properties;
  2062. int permissions;
  2063. bt_uuid_t uuid;
  2064. RETURN_IF_NULL(if_gatt);
  2065. VERIFY_SERVER_IF(2, server_if);
  2066. VERIFY_SERVICE_HANDLE(3, service_handle);
  2067. VERIFY_UUID(4, &uuid);
  2068. /* properties */
  2069. if (argc <= 5) {
  2070. haltest_error("No properties specified\n");
  2071. return;
  2072. }
  2073. properties = strtol(argv[5], NULL, 0);
  2074. /* permissions */
  2075. if (argc <= 6) {
  2076. haltest_error("No permissions specified\n");
  2077. return;
  2078. }
  2079. permissions = strtol(argv[6], NULL, 0);
  2080. EXEC(if_gatt->server->add_characteristic, server_if, service_handle,
  2081. &uuid, properties, permissions);
  2082. }
  2083. /* add_descriptor */
  2084. /* Same completion as gatts_unregister_server_c */
  2085. #define gatts_add_descriptor_c gatts_unregister_server_c
  2086. static void gatts_add_descriptor_p(int argc, const char *argv[])
  2087. {
  2088. int server_if;
  2089. int service_handle;
  2090. int permissions;
  2091. bt_uuid_t uuid;
  2092. RETURN_IF_NULL(if_gatt);
  2093. VERIFY_SERVER_IF(2, server_if);
  2094. VERIFY_SERVICE_HANDLE(3, service_handle);
  2095. VERIFY_UUID(4, &uuid);
  2096. /* permissions */
  2097. if (argc <= 5) {
  2098. haltest_error("No permissions specified\n");
  2099. return;
  2100. }
  2101. permissions = strtol(argv[5], NULL, 0);
  2102. EXEC(if_gatt->server->add_descriptor, server_if, service_handle, &uuid,
  2103. permissions);
  2104. }
  2105. /* start_service */
  2106. /* Same completion as gatts_unregister_server_c */
  2107. #define gatts_start_service_c gatts_unregister_server_c
  2108. static void gatts_start_service_p(int argc, const char *argv[])
  2109. {
  2110. int server_if;
  2111. int service_handle;
  2112. int transport;
  2113. RETURN_IF_NULL(if_gatt);
  2114. VERIFY_SERVER_IF(2, server_if);
  2115. VERIFY_SERVICE_HANDLE(3, service_handle);
  2116. /* transport */
  2117. if (argc <= 4) {
  2118. haltest_error("No transport specified\n");
  2119. return;
  2120. }
  2121. transport = strtol(argv[4], NULL, 0);
  2122. EXEC(if_gatt->server->start_service, server_if, service_handle,
  2123. transport);
  2124. }
  2125. /* stop_service */
  2126. /* Same completion as gatts_unregister_server_c */
  2127. #define gatts_stop_service_c gatts_unregister_server_c
  2128. static void gatts_stop_service_p(int argc, const char *argv[])
  2129. {
  2130. int server_if;
  2131. int service_handle;
  2132. RETURN_IF_NULL(if_gatt);
  2133. VERIFY_SERVER_IF(2, server_if);
  2134. VERIFY_SERVICE_HANDLE(3, service_handle);
  2135. EXEC(if_gatt->server->stop_service, server_if, service_handle);
  2136. }
  2137. /* delete_service */
  2138. /* Same completion as gatts_unregister_server_c */
  2139. #define gatts_delete_service_c gatts_unregister_server_c
  2140. static void gatts_delete_service_p(int argc, const char *argv[])
  2141. {
  2142. int server_if;
  2143. int service_handle;
  2144. RETURN_IF_NULL(if_gatt);
  2145. VERIFY_SERVER_IF(2, server_if);
  2146. VERIFY_SERVICE_HANDLE(3, service_handle);
  2147. EXEC(if_gatt->server->delete_service, server_if, service_handle);
  2148. }
  2149. /* send_indication */
  2150. static void gatts_send_indication_p(int argc, const char *argv[])
  2151. {
  2152. int server_if;
  2153. int attr_handle;
  2154. int conn_id;
  2155. int confirm;
  2156. char data[200];
  2157. int len = 0;
  2158. RETURN_IF_NULL(if_gatt);
  2159. VERIFY_SERVER_IF(2, server_if);
  2160. VERIFY_HANDLE(3, attr_handle);
  2161. VERIFY_CONN_ID(4, conn_id);
  2162. /* confirm */
  2163. if (argc <= 5) {
  2164. haltest_error("No transport specified\n");
  2165. return;
  2166. }
  2167. confirm = strtol(argv[5], NULL, 0);
  2168. GET_VERIFY_HEX_STRING(6, data, len);
  2169. EXEC(if_gatt->server->send_indication, server_if, attr_handle, conn_id,
  2170. len, confirm, data);
  2171. }
  2172. /* send_response */
  2173. static void gatts_send_response_p(int argc, const char *argv[])
  2174. {
  2175. int conn_id;
  2176. int trans_id;
  2177. int status;
  2178. btgatt_response_t data;
  2179. memset(&data, 0, sizeof(data));
  2180. RETURN_IF_NULL(if_gatt);
  2181. VERIFY_CONN_ID(2, conn_id);
  2182. VERIFY_TRANS_ID(3, trans_id);
  2183. VERIFY_STATUS(4, status);
  2184. VERIFY_HANDLE(5, data.attr_value.handle);
  2185. VERIFY_OFFSET(6, data.attr_value.offset);
  2186. data.attr_value.auth_req = 0;
  2187. data.attr_value.len = 0;
  2188. GET_VERIFY_HEX_STRING(7, data.attr_value.value, data.attr_value.len);
  2189. haltest_info("conn_id %d, trans_id %d, status %d", conn_id, trans_id,
  2190. status);
  2191. EXEC(if_gatt->server->send_response, conn_id, trans_id, status, &data);
  2192. }
  2193. #define GATTS_METHODH(n, h) METHOD(#n, gatts_##n##_p, NULL, h)
  2194. #define GATTS_METHODCH(n, h) METHOD(#n, gatts_##n##_p, gatts_##n##_c, h)
  2195. static struct method server_methods[] = {
  2196. GATTS_METHODH(register_server, "[<uuid>]"),
  2197. GATTS_METHODCH(unregister_server, "<server_if>"),
  2198. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  2199. GATTS_METHODCH(connect, "<server_if> <addr> [<is_direct>] [<transport>]"),
  2200. #else
  2201. GATTS_METHODCH(connect, "<server_if> <addr> [<is_direct>]"),
  2202. #endif
  2203. GATTS_METHODCH(disconnect, "<server_if> <addr> <conn_id>"),
  2204. GATTS_METHODCH(add_service, "<server_if> <srvc_id> <num_handles>"),
  2205. GATTS_METHODCH(add_included_service,
  2206. "<server_if> <service_handle> <included_handle>"),
  2207. GATTS_METHODCH(add_characteristic,
  2208. "<server_if> <service_handle> <uuid> <properites> <permissions>"),
  2209. GATTS_METHODCH(add_descriptor,
  2210. "<server_if> <service_handle> <uuid> <permissions>"),
  2211. GATTS_METHODCH(start_service,
  2212. "<server_if> <service_handle> <transport>"),
  2213. GATTS_METHODCH(stop_service, "<server_if> <service_handle>"),
  2214. GATTS_METHODCH(delete_service, "<server_if> <service_handle>"),
  2215. GATTS_METHODH(send_indication,
  2216. "<server_if> <attr_handle> <conn_id> <confirm> [<data>]"),
  2217. GATTS_METHODH(send_response,
  2218. "<conn_id> <trans_id> <status> <handle> <offset> [<data>]"),
  2219. END_METHOD
  2220. };
  2221. const struct interface gatt_server_if = {
  2222. .name = "gatts",
  2223. .methods = server_methods
  2224. };