server.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * BlueZ - Bluetooth protocol stack for Linux
  4. *
  5. * Copyright (C) 2010 Instituto Nokia de Tecnologia - INdT
  6. * Copyright (C) 2010 ST-Ericsson SA
  7. * Copyright (C) 2011 Tieto Poland
  8. *
  9. * Author: Marek Skowron <marek.skowron@tieto.com> for ST-Ericsson.
  10. * Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
  11. * for ST-Ericsson.
  12. *
  13. */
  14. #ifdef HAVE_CONFIG_H
  15. #include <config.h>
  16. #endif
  17. #include <errno.h>
  18. #include <glib.h>
  19. #include "lib/sdp.h"
  20. #include "lib/sdp_lib.h"
  21. #include "lib/uuid.h"
  22. #include "gdbus/gdbus.h"
  23. #include "btio/btio.h"
  24. #include "src/adapter.h"
  25. #include "src/sdpd.h"
  26. #include "src/log.h"
  27. #include "src/error.h"
  28. #include "src/dbus-common.h"
  29. #include "src/shared/timeout.h"
  30. #include "src/shared/util.h"
  31. #include "sap.h"
  32. #include "server.h"
  33. #define SAP_SERVER_INTERFACE "org.bluez.SimAccess1"
  34. #define SAP_SERVER_CHANNEL 8
  35. #define PADDING4(x) ((4 - ((x) & 0x03)) & 0x03)
  36. #define PARAMETER_SIZE(x) (sizeof(struct sap_parameter) + x + PADDING4(x))
  37. #define SAP_NO_REQ 0xFF
  38. #define SAP_DISCONNECTION_TYPE_CLIENT 0xFF
  39. #define SAP_TIMER_GRACEFUL_DISCONNECT 30
  40. #define SAP_TIMER_NO_ACTIVITY 30
  41. enum {
  42. SAP_STATE_DISCONNECTED,
  43. SAP_STATE_CONNECT_IN_PROGRESS,
  44. SAP_STATE_CONNECT_MODEM_BUSY,
  45. SAP_STATE_CONNECTED,
  46. SAP_STATE_GRACEFUL_DISCONNECT,
  47. SAP_STATE_IMMEDIATE_DISCONNECT,
  48. SAP_STATE_CLIENT_DISCONNECT
  49. };
  50. struct sap_connection {
  51. GIOChannel *io;
  52. uint32_t state;
  53. uint8_t processing_req;
  54. unsigned int timer_id;
  55. };
  56. struct sap_server {
  57. struct btd_adapter *adapter;
  58. uint32_t record_id;
  59. GIOChannel *listen_io;
  60. struct sap_connection *conn;
  61. };
  62. static void start_guard_timer(struct sap_server *server, guint interval);
  63. static void stop_guard_timer(struct sap_server *server);
  64. static bool guard_timeout(gpointer data);
  65. static size_t add_result_parameter(uint8_t result,
  66. struct sap_parameter *param)
  67. {
  68. param->id = SAP_PARAM_ID_RESULT_CODE;
  69. param->len = htons(SAP_PARAM_ID_RESULT_CODE_LEN);
  70. *param->val = result;
  71. return PARAMETER_SIZE(SAP_PARAM_ID_RESULT_CODE_LEN);
  72. }
  73. static int is_power_sim_off_req_allowed(uint8_t processing_req)
  74. {
  75. switch (processing_req) {
  76. case SAP_NO_REQ:
  77. case SAP_TRANSFER_APDU_REQ:
  78. case SAP_TRANSFER_ATR_REQ:
  79. case SAP_POWER_SIM_ON_REQ:
  80. case SAP_RESET_SIM_REQ:
  81. case SAP_TRANSFER_CARD_READER_STATUS_REQ:
  82. return 1;
  83. default:
  84. return 0;
  85. }
  86. }
  87. static int is_reset_sim_req_allowed(uint8_t processing_req)
  88. {
  89. switch (processing_req) {
  90. case SAP_NO_REQ:
  91. case SAP_TRANSFER_APDU_REQ:
  92. case SAP_TRANSFER_ATR_REQ:
  93. case SAP_TRANSFER_CARD_READER_STATUS_REQ:
  94. return 1;
  95. default:
  96. return 0;
  97. }
  98. }
  99. static int check_msg(struct sap_message *msg)
  100. {
  101. switch (msg->id) {
  102. case SAP_CONNECT_REQ:
  103. if (msg->nparam != 0x01)
  104. return -EBADMSG;
  105. if (msg->param->id != SAP_PARAM_ID_MAX_MSG_SIZE)
  106. return -EBADMSG;
  107. if (ntohs(msg->param->len) != SAP_PARAM_ID_MAX_MSG_SIZE_LEN)
  108. return -EBADMSG;
  109. break;
  110. case SAP_TRANSFER_APDU_REQ:
  111. if (msg->nparam != 0x01)
  112. return -EBADMSG;
  113. if (msg->param->id != SAP_PARAM_ID_COMMAND_APDU)
  114. if (msg->param->id != SAP_PARAM_ID_COMMAND_APDU7816)
  115. return -EBADMSG;
  116. if (msg->param->len == 0x00)
  117. return -EBADMSG;
  118. break;
  119. case SAP_SET_TRANSPORT_PROTOCOL_REQ:
  120. if (msg->nparam != 0x01)
  121. return -EBADMSG;
  122. if (msg->param->id != SAP_PARAM_ID_TRANSPORT_PROTOCOL)
  123. return -EBADMSG;
  124. if (ntohs(msg->param->len) != SAP_PARAM_ID_TRANSPORT_PROTO_LEN)
  125. return -EBADMSG;
  126. if (*msg->param->val != SAP_TRANSPORT_PROTOCOL_T0)
  127. if (*msg->param->val != SAP_TRANSPORT_PROTOCOL_T1)
  128. return -EBADMSG;
  129. break;
  130. case SAP_DISCONNECT_REQ:
  131. case SAP_TRANSFER_ATR_REQ:
  132. case SAP_POWER_SIM_OFF_REQ:
  133. case SAP_POWER_SIM_ON_REQ:
  134. case SAP_RESET_SIM_REQ:
  135. case SAP_TRANSFER_CARD_READER_STATUS_REQ:
  136. if (msg->nparam != 0x00)
  137. return -EBADMSG;
  138. break;
  139. }
  140. return 0;
  141. }
  142. static sdp_record_t *create_sap_record(uint8_t channel)
  143. {
  144. sdp_list_t *apseq, *aproto, *profiles, *proto[2], *root, *svclass_id;
  145. uuid_t sap_uuid, gt_uuid, root_uuid, l2cap, rfcomm;
  146. sdp_profile_desc_t profile;
  147. sdp_record_t *record;
  148. sdp_data_t *ch;
  149. record = sdp_record_alloc();
  150. if (!record)
  151. return NULL;
  152. sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
  153. root = sdp_list_append(NULL, &root_uuid);
  154. sdp_set_browse_groups(record, root);
  155. sdp_list_free(root, NULL);
  156. sdp_uuid16_create(&sap_uuid, SAP_SVCLASS_ID);
  157. svclass_id = sdp_list_append(NULL, &sap_uuid);
  158. sdp_uuid16_create(&gt_uuid, GENERIC_TELEPHONY_SVCLASS_ID);
  159. svclass_id = sdp_list_append(svclass_id, &gt_uuid);
  160. sdp_set_service_classes(record, svclass_id);
  161. sdp_list_free(svclass_id, NULL);
  162. sdp_uuid16_create(&profile.uuid, SAP_PROFILE_ID);
  163. profile.version = SAP_VERSION;
  164. profiles = sdp_list_append(NULL, &profile);
  165. sdp_set_profile_descs(record, profiles);
  166. sdp_list_free(profiles, NULL);
  167. sdp_uuid16_create(&l2cap, L2CAP_UUID);
  168. proto[0] = sdp_list_append(NULL, &l2cap);
  169. apseq = sdp_list_append(NULL, proto[0]);
  170. sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
  171. proto[1] = sdp_list_append(NULL, &rfcomm);
  172. ch = sdp_data_alloc(SDP_UINT8, &channel);
  173. proto[1] = sdp_list_append(proto[1], ch);
  174. apseq = sdp_list_append(apseq, proto[1]);
  175. aproto = sdp_list_append(NULL, apseq);
  176. sdp_set_access_protos(record, aproto);
  177. sdp_set_info_attr(record, "SIM Access Server", NULL, NULL);
  178. sdp_data_free(ch);
  179. sdp_list_free(proto[0], NULL);
  180. sdp_list_free(proto[1], NULL);
  181. sdp_list_free(apseq, NULL);
  182. sdp_list_free(aproto, NULL);
  183. return record;
  184. }
  185. static int send_message(struct sap_connection *conn, void *buf, size_t size)
  186. {
  187. size_t written = 0;
  188. GError *gerr = NULL;
  189. GIOStatus gstatus;
  190. SAP_VDBG("conn %p, size %zu", conn, size);
  191. gstatus = g_io_channel_write_chars(conn->io, buf, size, &written,
  192. &gerr);
  193. if (gstatus != G_IO_STATUS_NORMAL) {
  194. if (gerr)
  195. g_error_free(gerr);
  196. error("write error (0x%02x).", gstatus);
  197. return -EIO;
  198. }
  199. if (written != size) {
  200. error("written %zu bytes out of %zu", written, size);
  201. return -EIO;
  202. }
  203. return written;
  204. }
  205. static int disconnect_ind(struct sap_connection *conn, uint8_t disc_type)
  206. {
  207. char buf[SAP_BUF_SIZE];
  208. struct sap_message *msg = (struct sap_message *) buf;
  209. struct sap_parameter *param = (struct sap_parameter *) msg->param;
  210. size_t size = sizeof(struct sap_message);
  211. DBG("data %p state %d disc_type 0x%02x", conn, conn->state, disc_type);
  212. memset(buf, 0, sizeof(buf));
  213. msg->id = SAP_DISCONNECT_IND;
  214. msg->nparam = 0x01;
  215. /* Add disconnection type param. */
  216. param->id = SAP_PARAM_ID_DISCONNECT_IND;
  217. param->len = htons(SAP_PARAM_ID_DISCONNECT_IND_LEN);
  218. *param->val = disc_type;
  219. size += PARAMETER_SIZE(SAP_PARAM_ID_DISCONNECT_IND_LEN);
  220. return send_message(conn, buf, size);
  221. }
  222. static int sap_error_rsp(struct sap_connection *conn)
  223. {
  224. struct sap_message msg;
  225. memset(&msg, 0, sizeof(msg));
  226. msg.id = SAP_ERROR_RESP;
  227. error("SAP error (state %d pr 0x%02x).", conn->state,
  228. conn->processing_req);
  229. return send_message(conn, &msg, sizeof(msg));
  230. }
  231. static void connect_req(struct sap_server *server,
  232. struct sap_parameter *param)
  233. {
  234. struct sap_connection *conn = server->conn;
  235. uint16_t maxmsgsize;
  236. DBG("conn %p state %d", conn, conn->state);
  237. if (!param)
  238. goto error_rsp;
  239. if (conn->state != SAP_STATE_DISCONNECTED)
  240. goto error_rsp;
  241. stop_guard_timer(server);
  242. maxmsgsize = get_be16(&param->val);
  243. DBG("Connect MaxMsgSize: 0x%04x", maxmsgsize);
  244. conn->state = SAP_STATE_CONNECT_IN_PROGRESS;
  245. if (maxmsgsize <= SAP_BUF_SIZE) {
  246. conn->processing_req = SAP_CONNECT_REQ;
  247. sap_connect_req(server, maxmsgsize);
  248. } else {
  249. sap_connect_rsp(server, SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED);
  250. }
  251. return;
  252. error_rsp:
  253. sap_error_rsp(conn);
  254. }
  255. static int disconnect_req(struct sap_server *server, uint8_t disc_type)
  256. {
  257. struct sap_connection *conn = server->conn;
  258. DBG("conn %p state %d disc_type 0x%02x", conn, conn->state, disc_type);
  259. switch (disc_type) {
  260. case SAP_DISCONNECTION_TYPE_GRACEFUL:
  261. if (conn->state == SAP_STATE_DISCONNECTED ||
  262. conn->state == SAP_STATE_CONNECT_IN_PROGRESS ||
  263. conn->state == SAP_STATE_CONNECT_MODEM_BUSY)
  264. return -EPERM;
  265. if (conn->state == SAP_STATE_CONNECTED) {
  266. conn->state = SAP_STATE_GRACEFUL_DISCONNECT;
  267. conn->processing_req = SAP_NO_REQ;
  268. disconnect_ind(conn, disc_type);
  269. /* Timer will disconnect if client won't do.*/
  270. start_guard_timer(server,
  271. SAP_TIMER_GRACEFUL_DISCONNECT);
  272. }
  273. return 0;
  274. case SAP_DISCONNECTION_TYPE_IMMEDIATE:
  275. if (conn->state == SAP_STATE_DISCONNECTED ||
  276. conn->state == SAP_STATE_CONNECT_IN_PROGRESS ||
  277. conn->state == SAP_STATE_CONNECT_MODEM_BUSY)
  278. return -EPERM;
  279. if (conn->state == SAP_STATE_CONNECTED ||
  280. conn->state == SAP_STATE_GRACEFUL_DISCONNECT) {
  281. conn->state = SAP_STATE_IMMEDIATE_DISCONNECT;
  282. conn->processing_req = SAP_NO_REQ;
  283. stop_guard_timer(server);
  284. disconnect_ind(conn, disc_type);
  285. sap_disconnect_req(server, 0);
  286. }
  287. return 0;
  288. case SAP_DISCONNECTION_TYPE_CLIENT:
  289. if (conn->state != SAP_STATE_CONNECTED &&
  290. conn->state != SAP_STATE_GRACEFUL_DISCONNECT) {
  291. sap_error_rsp(conn);
  292. return -EPERM;
  293. }
  294. conn->state = SAP_STATE_CLIENT_DISCONNECT;
  295. conn->processing_req = SAP_NO_REQ;
  296. stop_guard_timer(server);
  297. sap_disconnect_req(server, 0);
  298. return 0;
  299. default:
  300. error("Unknown disconnection type (0x%02x).", disc_type);
  301. return -EINVAL;
  302. }
  303. }
  304. static void transfer_apdu_req(struct sap_server *server,
  305. struct sap_parameter *param)
  306. {
  307. struct sap_connection *conn = server->conn;
  308. SAP_VDBG("conn %p state %d", conn, conn->state);
  309. if (!param)
  310. goto error_rsp;
  311. param->len = ntohs(param->len);
  312. if (conn->state != SAP_STATE_CONNECTED &&
  313. conn->state != SAP_STATE_GRACEFUL_DISCONNECT)
  314. goto error_rsp;
  315. if (conn->processing_req != SAP_NO_REQ)
  316. goto error_rsp;
  317. conn->processing_req = SAP_TRANSFER_APDU_REQ;
  318. sap_transfer_apdu_req(server, param);
  319. return;
  320. error_rsp:
  321. sap_error_rsp(conn);
  322. }
  323. static void transfer_atr_req(struct sap_server *server)
  324. {
  325. struct sap_connection *conn = server->conn;
  326. DBG("conn %p state %d", conn, conn->state);
  327. if (conn->state != SAP_STATE_CONNECTED)
  328. goto error_rsp;
  329. if (conn->processing_req != SAP_NO_REQ)
  330. goto error_rsp;
  331. conn->processing_req = SAP_TRANSFER_ATR_REQ;
  332. sap_transfer_atr_req(server);
  333. return;
  334. error_rsp:
  335. sap_error_rsp(conn);
  336. }
  337. static void power_sim_off_req(struct sap_server *server)
  338. {
  339. struct sap_connection *conn = server->conn;
  340. DBG("conn %p state %d", conn, conn->state);
  341. if (conn->state != SAP_STATE_CONNECTED)
  342. goto error_rsp;
  343. if (!is_power_sim_off_req_allowed(conn->processing_req))
  344. goto error_rsp;
  345. conn->processing_req = SAP_POWER_SIM_OFF_REQ;
  346. sap_power_sim_off_req(server);
  347. return;
  348. error_rsp:
  349. sap_error_rsp(conn);
  350. }
  351. static void power_sim_on_req(struct sap_server *server)
  352. {
  353. struct sap_connection *conn = server->conn;
  354. DBG("conn %p state %d", conn, conn->state);
  355. if (conn->state != SAP_STATE_CONNECTED)
  356. goto error_rsp;
  357. if (conn->processing_req != SAP_NO_REQ)
  358. goto error_rsp;
  359. conn->processing_req = SAP_POWER_SIM_ON_REQ;
  360. sap_power_sim_on_req(server);
  361. return;
  362. error_rsp:
  363. sap_error_rsp(conn);
  364. }
  365. static void reset_sim_req(struct sap_server *server)
  366. {
  367. struct sap_connection *conn = server->conn;
  368. DBG("conn %p state %d", conn, conn->state);
  369. if (conn->state != SAP_STATE_CONNECTED)
  370. goto error_rsp;
  371. if (!is_reset_sim_req_allowed(conn->processing_req))
  372. goto error_rsp;
  373. conn->processing_req = SAP_RESET_SIM_REQ;
  374. sap_reset_sim_req(server);
  375. return;
  376. error_rsp:
  377. sap_error_rsp(conn);
  378. }
  379. static void transfer_card_reader_status_req(struct sap_server *server)
  380. {
  381. struct sap_connection *conn = server->conn;
  382. DBG("conn %p state %d", conn, conn->state);
  383. if (conn->state != SAP_STATE_CONNECTED)
  384. goto error_rsp;
  385. if (conn->processing_req != SAP_NO_REQ)
  386. goto error_rsp;
  387. conn->processing_req = SAP_TRANSFER_CARD_READER_STATUS_REQ;
  388. sap_transfer_card_reader_status_req(server);
  389. return;
  390. error_rsp:
  391. sap_error_rsp(conn);
  392. }
  393. static void set_transport_protocol_req(struct sap_server *server,
  394. struct sap_parameter *param)
  395. {
  396. struct sap_connection *conn = server->conn;
  397. if (!param)
  398. goto error_rsp;
  399. DBG("conn %p state %d param %p", conn, conn->state, param);
  400. if (conn->state != SAP_STATE_CONNECTED)
  401. goto error_rsp;
  402. if (conn->processing_req != SAP_NO_REQ)
  403. goto error_rsp;
  404. conn->processing_req = SAP_SET_TRANSPORT_PROTOCOL_REQ;
  405. sap_set_transport_protocol_req(server, param);
  406. return;
  407. error_rsp:
  408. sap_error_rsp(conn);
  409. }
  410. static void start_guard_timer(struct sap_server *server, guint interval)
  411. {
  412. struct sap_connection *conn = server->conn;
  413. if (!conn)
  414. return;
  415. if (!conn->timer_id)
  416. conn->timer_id = timeout_add_seconds(interval, guard_timeout,
  417. server, NULL);
  418. else
  419. error("Timer is already active.");
  420. }
  421. static void stop_guard_timer(struct sap_server *server)
  422. {
  423. struct sap_connection *conn = server->conn;
  424. if (conn && conn->timer_id) {
  425. timeout_remove(conn->timer_id);
  426. conn->timer_id = 0;
  427. }
  428. }
  429. static bool guard_timeout(gpointer data)
  430. {
  431. struct sap_server *server = data;
  432. struct sap_connection *conn = server->conn;
  433. if (!conn)
  434. return FALSE;
  435. DBG("conn %p state %d pr 0x%02x", conn, conn->state,
  436. conn->processing_req);
  437. conn->timer_id = 0;
  438. switch (conn->state) {
  439. case SAP_STATE_DISCONNECTED:
  440. /* Client opened RFCOMM channel but didn't send CONNECT_REQ,
  441. * in fixed time or client disconnected SAP connection but
  442. * didn't closed RFCOMM channel in fixed time.*/
  443. if (conn->io) {
  444. g_io_channel_shutdown(conn->io, TRUE, NULL);
  445. g_io_channel_unref(conn->io);
  446. conn->io = NULL;
  447. }
  448. break;
  449. case SAP_STATE_GRACEFUL_DISCONNECT:
  450. /* Client didn't disconnect SAP connection in fixed time,
  451. * so close SAP connection immediately. */
  452. disconnect_req(server, SAP_DISCONNECTION_TYPE_IMMEDIATE);
  453. break;
  454. default:
  455. error("Unexpected state (%d).", conn->state);
  456. break;
  457. }
  458. return FALSE;
  459. }
  460. static void sap_set_connected(struct sap_server *server)
  461. {
  462. server->conn->state = SAP_STATE_CONNECTED;
  463. g_dbus_emit_property_changed(btd_get_dbus_connection(),
  464. adapter_get_path(server->adapter),
  465. SAP_SERVER_INTERFACE, "Connected");
  466. }
  467. int sap_connect_rsp(void *sap_device, uint8_t status)
  468. {
  469. struct sap_server *server = sap_device;
  470. struct sap_connection *conn = server->conn;
  471. char buf[SAP_BUF_SIZE];
  472. struct sap_message *msg = (struct sap_message *) buf;
  473. struct sap_parameter *param = (struct sap_parameter *) msg->param;
  474. size_t size = sizeof(struct sap_message);
  475. if (!conn)
  476. return -EINVAL;
  477. DBG("state %d pr 0x%02x status 0x%02x", conn->state,
  478. conn->processing_req, status);
  479. if (conn->state != SAP_STATE_CONNECT_IN_PROGRESS)
  480. return -EPERM;
  481. memset(buf, 0, sizeof(buf));
  482. msg->id = SAP_CONNECT_RESP;
  483. msg->nparam = 0x01;
  484. /* Add connection status */
  485. param->id = SAP_PARAM_ID_CONN_STATUS;
  486. param->len = htons(SAP_PARAM_ID_CONN_STATUS_LEN);
  487. *param->val = status;
  488. size += PARAMETER_SIZE(SAP_PARAM_ID_CONN_STATUS_LEN);
  489. switch (status) {
  490. case SAP_STATUS_OK:
  491. sap_set_connected(server);
  492. break;
  493. case SAP_STATUS_OK_ONGOING_CALL:
  494. DBG("ongoing call. Wait for reset indication!");
  495. conn->state = SAP_STATE_CONNECT_MODEM_BUSY;
  496. break;
  497. case SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED: /* Add MaxMsgSize */
  498. msg->nparam++;
  499. param = (struct sap_parameter *) &buf[size];
  500. param->id = SAP_PARAM_ID_MAX_MSG_SIZE;
  501. param->len = htons(SAP_PARAM_ID_MAX_MSG_SIZE_LEN);
  502. put_be16(SAP_BUF_SIZE, &param->val);
  503. size += PARAMETER_SIZE(SAP_PARAM_ID_MAX_MSG_SIZE_LEN);
  504. /* fall through */
  505. default:
  506. conn->state = SAP_STATE_DISCONNECTED;
  507. /* Timer will shutdown channel if client doesn't send
  508. * CONNECT_REQ or doesn't shutdown channel itself.*/
  509. start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
  510. break;
  511. }
  512. conn->processing_req = SAP_NO_REQ;
  513. return send_message(conn, buf, size);
  514. }
  515. int sap_disconnect_rsp(void *sap_device)
  516. {
  517. struct sap_server *server = sap_device;
  518. struct sap_connection *conn = server->conn;
  519. struct sap_message msg;
  520. if (!conn)
  521. return -EINVAL;
  522. DBG("state %d pr 0x%02x", conn->state, conn->processing_req);
  523. switch (conn->state) {
  524. case SAP_STATE_CLIENT_DISCONNECT:
  525. memset(&msg, 0, sizeof(msg));
  526. msg.id = SAP_DISCONNECT_RESP;
  527. conn->state = SAP_STATE_DISCONNECTED;
  528. conn->processing_req = SAP_NO_REQ;
  529. /* Timer will close channel if client doesn't do it.*/
  530. start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
  531. return send_message(conn, &msg, sizeof(msg));
  532. case SAP_STATE_IMMEDIATE_DISCONNECT:
  533. conn->state = SAP_STATE_DISCONNECTED;
  534. conn->processing_req = SAP_NO_REQ;
  535. if (conn->io) {
  536. g_io_channel_shutdown(conn->io, TRUE, NULL);
  537. g_io_channel_unref(conn->io);
  538. conn->io = NULL;
  539. }
  540. return 0;
  541. default:
  542. break;
  543. }
  544. return 0;
  545. }
  546. int sap_transfer_apdu_rsp(void *sap_device, uint8_t result, uint8_t *apdu,
  547. uint16_t length)
  548. {
  549. struct sap_server *server = sap_device;
  550. struct sap_connection *conn = server->conn;
  551. char buf[SAP_BUF_SIZE];
  552. struct sap_message *msg = (struct sap_message *) buf;
  553. struct sap_parameter *param = (struct sap_parameter *) msg->param;
  554. size_t size = sizeof(struct sap_message);
  555. if (!conn)
  556. return -EINVAL;
  557. SAP_VDBG("state %d pr 0x%02x", conn->state, conn->processing_req);
  558. if (conn->processing_req != SAP_TRANSFER_APDU_REQ)
  559. return 0;
  560. if (result == SAP_RESULT_OK && (!apdu || (apdu && length == 0x00)))
  561. return -EINVAL;
  562. memset(buf, 0, sizeof(buf));
  563. msg->id = SAP_TRANSFER_APDU_RESP;
  564. msg->nparam = 0x01;
  565. size += add_result_parameter(result, param);
  566. /* Add APDU response. */
  567. if (result == SAP_RESULT_OK) {
  568. msg->nparam++;
  569. param = (struct sap_parameter *) &buf[size];
  570. param->id = SAP_PARAM_ID_RESPONSE_APDU;
  571. param->len = htons(length);
  572. size += PARAMETER_SIZE(length);
  573. if (size > SAP_BUF_SIZE)
  574. return -EOVERFLOW;
  575. memcpy(param->val, apdu, length);
  576. }
  577. conn->processing_req = SAP_NO_REQ;
  578. return send_message(conn, buf, size);
  579. }
  580. int sap_transfer_atr_rsp(void *sap_device, uint8_t result, uint8_t *atr,
  581. uint16_t length)
  582. {
  583. struct sap_server *server = sap_device;
  584. struct sap_connection *conn = server->conn;
  585. char buf[SAP_BUF_SIZE];
  586. struct sap_message *msg = (struct sap_message *) buf;
  587. struct sap_parameter *param = (struct sap_parameter *) msg->param;
  588. size_t size = sizeof(struct sap_message);
  589. if (!conn)
  590. return -EINVAL;
  591. DBG("result 0x%02x state %d pr 0x%02x len %d", result, conn->state,
  592. conn->processing_req, length);
  593. if (conn->processing_req != SAP_TRANSFER_ATR_REQ)
  594. return 0;
  595. if (result == SAP_RESULT_OK && (!atr || (atr && length == 0x00)))
  596. return -EINVAL;
  597. memset(buf, 0, sizeof(buf));
  598. msg->id = SAP_TRANSFER_ATR_RESP;
  599. msg->nparam = 0x01;
  600. size += add_result_parameter(result, param);
  601. /* Add ATR response */
  602. if (result == SAP_RESULT_OK) {
  603. msg->nparam++;
  604. param = (struct sap_parameter *) &buf[size];
  605. param->id = SAP_PARAM_ID_ATR;
  606. param->len = htons(length);
  607. size += PARAMETER_SIZE(length);
  608. if (size > SAP_BUF_SIZE)
  609. return -EOVERFLOW;
  610. memcpy(param->val, atr, length);
  611. }
  612. conn->processing_req = SAP_NO_REQ;
  613. return send_message(conn, buf, size);
  614. }
  615. int sap_power_sim_off_rsp(void *sap_device, uint8_t result)
  616. {
  617. struct sap_server *server = sap_device;
  618. struct sap_connection *conn = server->conn;
  619. char buf[SAP_BUF_SIZE];
  620. struct sap_message *msg = (struct sap_message *) buf;
  621. size_t size = sizeof(struct sap_message);
  622. if (!conn)
  623. return -EINVAL;
  624. DBG("state %d pr 0x%02x", conn->state, conn->processing_req);
  625. if (conn->processing_req != SAP_POWER_SIM_OFF_REQ)
  626. return 0;
  627. memset(buf, 0, sizeof(buf));
  628. msg->id = SAP_POWER_SIM_OFF_RESP;
  629. msg->nparam = 0x01;
  630. size += add_result_parameter(result, msg->param);
  631. conn->processing_req = SAP_NO_REQ;
  632. return send_message(conn, buf, size);
  633. }
  634. int sap_power_sim_on_rsp(void *sap_device, uint8_t result)
  635. {
  636. struct sap_server *server = sap_device;
  637. struct sap_connection *conn = server->conn;
  638. char buf[SAP_BUF_SIZE];
  639. struct sap_message *msg = (struct sap_message *) buf;
  640. size_t size = sizeof(struct sap_message);
  641. if (!conn)
  642. return -EINVAL;
  643. DBG("state %d pr 0x%02x", conn->state, conn->processing_req);
  644. if (conn->processing_req != SAP_POWER_SIM_ON_REQ)
  645. return 0;
  646. memset(buf, 0, sizeof(buf));
  647. msg->id = SAP_POWER_SIM_ON_RESP;
  648. msg->nparam = 0x01;
  649. size += add_result_parameter(result, msg->param);
  650. conn->processing_req = SAP_NO_REQ;
  651. return send_message(conn, buf, size);
  652. }
  653. int sap_reset_sim_rsp(void *sap_device, uint8_t result)
  654. {
  655. struct sap_server *server = sap_device;
  656. struct sap_connection *conn = server->conn;
  657. char buf[SAP_BUF_SIZE];
  658. struct sap_message *msg = (struct sap_message *) buf;
  659. size_t size = sizeof(struct sap_message);
  660. if (!conn)
  661. return -EINVAL;
  662. DBG("state %d pr 0x%02x result 0x%02x", conn->state,
  663. conn->processing_req, result);
  664. if (conn->processing_req != SAP_RESET_SIM_REQ)
  665. return 0;
  666. memset(buf, 0, sizeof(buf));
  667. msg->id = SAP_RESET_SIM_RESP;
  668. msg->nparam = 0x01;
  669. size += add_result_parameter(result, msg->param);
  670. conn->processing_req = SAP_NO_REQ;
  671. return send_message(conn, buf, size);
  672. }
  673. int sap_transfer_card_reader_status_rsp(void *sap_device, uint8_t result,
  674. uint8_t status)
  675. {
  676. struct sap_server *server = sap_device;
  677. struct sap_connection *conn = server->conn;
  678. char buf[SAP_BUF_SIZE];
  679. struct sap_message *msg = (struct sap_message *) buf;
  680. struct sap_parameter *param = (struct sap_parameter *) msg->param;
  681. size_t size = sizeof(struct sap_message);
  682. if (!conn)
  683. return -EINVAL;
  684. DBG("state %d pr 0x%02x result 0x%02x", conn->state,
  685. conn->processing_req, result);
  686. if (conn->processing_req != SAP_TRANSFER_CARD_READER_STATUS_REQ)
  687. return 0;
  688. memset(buf, 0, sizeof(buf));
  689. msg->id = SAP_TRANSFER_CARD_READER_STATUS_RESP;
  690. msg->nparam = 0x01;
  691. size += add_result_parameter(result, param);
  692. /* Add card reader status. */
  693. if (result == SAP_RESULT_OK) {
  694. msg->nparam++;
  695. param = (struct sap_parameter *) &buf[size];
  696. param->id = SAP_PARAM_ID_CARD_READER_STATUS;
  697. param->len = htons(SAP_PARAM_ID_CARD_READER_STATUS_LEN);
  698. *param->val = status;
  699. size += PARAMETER_SIZE(SAP_PARAM_ID_CARD_READER_STATUS_LEN);
  700. }
  701. conn->processing_req = SAP_NO_REQ;
  702. return send_message(conn, buf, size);
  703. }
  704. int sap_transport_protocol_rsp(void *sap_device, uint8_t result)
  705. {
  706. struct sap_server *server = sap_device;
  707. struct sap_connection *conn = server->conn;
  708. char buf[SAP_BUF_SIZE];
  709. struct sap_message *msg = (struct sap_message *) buf;
  710. size_t size = sizeof(struct sap_message);
  711. if (!conn)
  712. return -EINVAL;
  713. DBG("state %d pr 0x%02x result 0x%02x", conn->state,
  714. conn->processing_req, result);
  715. if (conn->processing_req != SAP_SET_TRANSPORT_PROTOCOL_REQ)
  716. return 0;
  717. memset(buf, 0, sizeof(buf));
  718. msg->id = SAP_SET_TRANSPORT_PROTOCOL_RESP;
  719. msg->nparam = 0x01;
  720. size += add_result_parameter(result, msg->param);
  721. conn->processing_req = SAP_NO_REQ;
  722. return send_message(conn, buf, size);
  723. }
  724. int sap_status_ind(void *sap_device, uint8_t status_change)
  725. {
  726. struct sap_server *server = sap_device;
  727. struct sap_connection *conn = server->conn;
  728. char buf[SAP_BUF_SIZE];
  729. struct sap_message *msg = (struct sap_message *) buf;
  730. struct sap_parameter *param = (struct sap_parameter *) msg->param;
  731. size_t size = sizeof(struct sap_message);
  732. if (!conn)
  733. return -EINVAL;
  734. DBG("state %d pr 0x%02x sc 0x%02x", conn->state, conn->processing_req,
  735. status_change);
  736. switch (conn->state) {
  737. case SAP_STATE_CONNECT_MODEM_BUSY:
  738. if (status_change != SAP_STATUS_CHANGE_CARD_RESET)
  739. break;
  740. /* Change state to connected after ongoing call ended */
  741. sap_set_connected(server);
  742. /* fall through */
  743. case SAP_STATE_CONNECTED:
  744. case SAP_STATE_GRACEFUL_DISCONNECT:
  745. memset(buf, 0, sizeof(buf));
  746. msg->id = SAP_STATUS_IND;
  747. msg->nparam = 0x01;
  748. /* Add status change. */
  749. param->id = SAP_PARAM_ID_STATUS_CHANGE;
  750. param->len = htons(SAP_PARAM_ID_STATUS_CHANGE_LEN);
  751. *param->val = status_change;
  752. size += PARAMETER_SIZE(SAP_PARAM_ID_STATUS_CHANGE_LEN);
  753. return send_message(conn, buf, size);
  754. case SAP_STATE_DISCONNECTED:
  755. case SAP_STATE_CONNECT_IN_PROGRESS:
  756. case SAP_STATE_IMMEDIATE_DISCONNECT:
  757. case SAP_STATE_CLIENT_DISCONNECT:
  758. break;
  759. }
  760. return 0;
  761. }
  762. int sap_disconnect_ind(void *sap_device, uint8_t disc_type)
  763. {
  764. return disconnect_req(sap_device, SAP_DISCONNECTION_TYPE_IMMEDIATE);
  765. }
  766. static int handle_cmd(struct sap_server *server, void *buf, size_t size)
  767. {
  768. struct sap_connection *conn = server->conn;
  769. struct sap_message *msg = buf;
  770. if (!conn)
  771. return -EINVAL;
  772. if (size < sizeof(struct sap_message))
  773. goto error_rsp;
  774. if (msg->nparam != 0 && size < (sizeof(struct sap_message) +
  775. sizeof(struct sap_parameter) + 4))
  776. goto error_rsp;
  777. if (check_msg(msg) < 0)
  778. goto error_rsp;
  779. switch (msg->id) {
  780. case SAP_CONNECT_REQ:
  781. connect_req(server, msg->param);
  782. return 0;
  783. case SAP_DISCONNECT_REQ:
  784. disconnect_req(server, SAP_DISCONNECTION_TYPE_CLIENT);
  785. return 0;
  786. case SAP_TRANSFER_APDU_REQ:
  787. transfer_apdu_req(server, msg->param);
  788. return 0;
  789. case SAP_TRANSFER_ATR_REQ:
  790. transfer_atr_req(server);
  791. return 0;
  792. case SAP_POWER_SIM_OFF_REQ:
  793. power_sim_off_req(server);
  794. return 0;
  795. case SAP_POWER_SIM_ON_REQ:
  796. power_sim_on_req(server);
  797. return 0;
  798. case SAP_RESET_SIM_REQ:
  799. reset_sim_req(server);
  800. return 0;
  801. case SAP_TRANSFER_CARD_READER_STATUS_REQ:
  802. transfer_card_reader_status_req(server);
  803. return 0;
  804. case SAP_SET_TRANSPORT_PROTOCOL_REQ:
  805. set_transport_protocol_req(server, msg->param);
  806. return 0;
  807. default:
  808. DBG("Unknown SAP message id 0x%02x.", msg->id);
  809. break;
  810. }
  811. error_rsp:
  812. DBG("Invalid SAP message format.");
  813. sap_error_rsp(conn);
  814. return -EBADMSG;
  815. }
  816. static void sap_server_remove_conn(struct sap_server *server)
  817. {
  818. struct sap_connection *conn = server->conn;
  819. DBG("conn %p", conn);
  820. if (!conn)
  821. return;
  822. if (conn->io) {
  823. g_io_channel_shutdown(conn->io, TRUE, NULL);
  824. g_io_channel_unref(conn->io);
  825. }
  826. g_free(conn);
  827. server->conn = NULL;
  828. }
  829. static gboolean sap_io_cb(GIOChannel *io, GIOCondition cond, gpointer data)
  830. {
  831. char buf[SAP_BUF_SIZE];
  832. size_t bytes_read = 0;
  833. GError *gerr = NULL;
  834. GIOStatus gstatus;
  835. SAP_VDBG("conn %p io %p", conn, io);
  836. if (cond & G_IO_NVAL) {
  837. DBG("ERR (G_IO_NVAL) on rfcomm socket.");
  838. return FALSE;
  839. }
  840. if (cond & G_IO_ERR) {
  841. DBG("ERR (G_IO_ERR) on rfcomm socket.");
  842. return FALSE;
  843. }
  844. if (cond & G_IO_HUP) {
  845. DBG("HUP on rfcomm socket.");
  846. return FALSE;
  847. }
  848. gstatus = g_io_channel_read_chars(io, buf, sizeof(buf) - 1,
  849. &bytes_read, &gerr);
  850. if (gstatus != G_IO_STATUS_NORMAL) {
  851. if (gerr)
  852. g_error_free(gerr);
  853. return TRUE;
  854. }
  855. if (handle_cmd(data, buf, bytes_read) < 0)
  856. error("SAP protocol processing failure.");
  857. return TRUE;
  858. }
  859. static void sap_io_destroy(void *data)
  860. {
  861. struct sap_server *server = data;
  862. struct sap_connection *conn = server->conn;
  863. DBG("conn %p", conn);
  864. if (!conn || !conn->io)
  865. return;
  866. stop_guard_timer(server);
  867. if (conn->state != SAP_STATE_CONNECT_IN_PROGRESS &&
  868. conn->state != SAP_STATE_CONNECT_MODEM_BUSY)
  869. g_dbus_emit_property_changed(btd_get_dbus_connection(),
  870. adapter_get_path(server->adapter),
  871. SAP_SERVER_INTERFACE,
  872. "Connected");
  873. if (conn->state == SAP_STATE_CONNECT_IN_PROGRESS ||
  874. conn->state == SAP_STATE_CONNECT_MODEM_BUSY ||
  875. conn->state == SAP_STATE_CONNECTED ||
  876. conn->state == SAP_STATE_GRACEFUL_DISCONNECT)
  877. sap_disconnect_req(server, 1);
  878. sap_server_remove_conn(server);
  879. }
  880. static void sap_connect_cb(GIOChannel *io, GError *gerr, gpointer data)
  881. {
  882. struct sap_server *server = data;
  883. struct sap_connection *conn = server->conn;
  884. DBG("conn %p, io %p", conn, io);
  885. if (!conn)
  886. return;
  887. /* Timer will shutdown the channel in case of lack of client
  888. activity */
  889. start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
  890. g_io_add_watch_full(io, G_PRIORITY_DEFAULT,
  891. G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
  892. sap_io_cb, server, sap_io_destroy);
  893. }
  894. static void connect_auth_cb(DBusError *derr, void *data)
  895. {
  896. struct sap_server *server = data;
  897. struct sap_connection *conn = server->conn;
  898. GError *gerr = NULL;
  899. DBG("conn %p", conn);
  900. if (!conn)
  901. return;
  902. if (derr && dbus_error_is_set(derr)) {
  903. error("Access has been denied (%s)", derr->message);
  904. sap_server_remove_conn(server);
  905. return;
  906. }
  907. if (!bt_io_accept(conn->io, sap_connect_cb, server, NULL, &gerr)) {
  908. error("bt_io_accept: %s", gerr->message);
  909. g_error_free(gerr);
  910. sap_server_remove_conn(server);
  911. return;
  912. }
  913. DBG("Access has been granted.");
  914. }
  915. static void connect_confirm_cb(GIOChannel *io, gpointer data)
  916. {
  917. struct sap_server *server = data;
  918. struct sap_connection *conn = server->conn;
  919. GError *gerr = NULL;
  920. bdaddr_t src, dst;
  921. char dstaddr[18];
  922. guint ret;
  923. DBG("conn %p io %p", conn, io);
  924. if (!io)
  925. return;
  926. if (conn) {
  927. DBG("Another SAP connection already exists.");
  928. g_io_channel_shutdown(io, TRUE, NULL);
  929. return;
  930. }
  931. conn = g_try_new0(struct sap_connection, 1);
  932. if (!conn) {
  933. error("Can't allocate memory for incoming SAP connection.");
  934. g_io_channel_shutdown(io, TRUE, NULL);
  935. return;
  936. }
  937. g_io_channel_set_encoding(io, NULL, NULL);
  938. g_io_channel_set_buffered(io, FALSE);
  939. server->conn = conn;
  940. conn->io = g_io_channel_ref(io);
  941. conn->state = SAP_STATE_DISCONNECTED;
  942. bt_io_get(io, &gerr,
  943. BT_IO_OPT_SOURCE_BDADDR, &src,
  944. BT_IO_OPT_DEST_BDADDR, &dst,
  945. BT_IO_OPT_INVALID);
  946. if (gerr) {
  947. error("%s", gerr->message);
  948. g_error_free(gerr);
  949. sap_server_remove_conn(server);
  950. return;
  951. }
  952. ba2str(&dst, dstaddr);
  953. ret = btd_request_authorization(&src, &dst, SAP_UUID, connect_auth_cb,
  954. server);
  955. if (ret == 0) {
  956. error("Authorization failure");
  957. sap_server_remove_conn(server);
  958. return;
  959. }
  960. DBG("Authorizing incoming SAP connection from %s", dstaddr);
  961. }
  962. static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
  963. void *data)
  964. {
  965. struct sap_server *server = data;
  966. if (!server)
  967. return btd_error_failed(msg, "Server internal error.");
  968. DBG("conn %p", server->conn);
  969. if (!server->conn)
  970. return btd_error_failed(msg, "Client already disconnected");
  971. if (disconnect_req(server, SAP_DISCONNECTION_TYPE_GRACEFUL) < 0)
  972. return btd_error_failed(msg, "There is no active connection");
  973. return dbus_message_new_method_return(msg);
  974. }
  975. static gboolean server_property_get_connected(
  976. const GDBusPropertyTable *property,
  977. DBusMessageIter *iter, void *data)
  978. {
  979. struct sap_server *server = data;
  980. struct sap_connection *conn = server->conn;
  981. dbus_bool_t connected;
  982. if (!conn) {
  983. connected = FALSE;
  984. goto append;
  985. }
  986. connected = (conn->state == SAP_STATE_CONNECTED ||
  987. conn->state == SAP_STATE_GRACEFUL_DISCONNECT);
  988. append:
  989. dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &connected);
  990. return TRUE;
  991. }
  992. static const GDBusMethodTable server_methods[] = {
  993. { GDBUS_METHOD("Disconnect", NULL, NULL, disconnect) },
  994. { }
  995. };
  996. static const GDBusPropertyTable server_properties[] = {
  997. { "Connected", "b", server_property_get_connected },
  998. { }
  999. };
  1000. static void server_remove(struct sap_server *server)
  1001. {
  1002. if (!server)
  1003. return;
  1004. sap_server_remove_conn(server);
  1005. adapter_service_remove(server->adapter, server->record_id);
  1006. if (server->listen_io) {
  1007. g_io_channel_shutdown(server->listen_io, TRUE, NULL);
  1008. g_io_channel_unref(server->listen_io);
  1009. server->listen_io = NULL;
  1010. }
  1011. btd_adapter_unref(server->adapter);
  1012. g_free(server);
  1013. }
  1014. static void destroy_sap_interface(void *data)
  1015. {
  1016. struct sap_server *server = data;
  1017. DBG("Unregistered interface %s on path %s", SAP_SERVER_INTERFACE,
  1018. adapter_get_path(server->adapter));
  1019. server_remove(server);
  1020. }
  1021. int sap_server_register(struct btd_adapter *adapter)
  1022. {
  1023. sdp_record_t *record = NULL;
  1024. GError *gerr = NULL;
  1025. GIOChannel *io;
  1026. struct sap_server *server;
  1027. if (sap_init() < 0) {
  1028. error("Sap driver initialization failed.");
  1029. return -1;
  1030. }
  1031. record = create_sap_record(SAP_SERVER_CHANNEL);
  1032. if (!record) {
  1033. error("Creating SAP SDP record failed.");
  1034. goto sdp_err;
  1035. }
  1036. if (adapter_service_add(adapter, record) < 0) {
  1037. error("Adding SAP SDP record to the SDP server failed.");
  1038. sdp_record_free(record);
  1039. goto sdp_err;
  1040. }
  1041. server = g_new0(struct sap_server, 1);
  1042. server->adapter = btd_adapter_ref(adapter);
  1043. server->record_id = record->handle;
  1044. io = bt_io_listen(NULL, connect_confirm_cb, server,
  1045. NULL, &gerr,
  1046. BT_IO_OPT_SOURCE_BDADDR,
  1047. btd_adapter_get_address(adapter),
  1048. BT_IO_OPT_CHANNEL, SAP_SERVER_CHANNEL,
  1049. BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH,
  1050. BT_IO_OPT_CENTRAL, TRUE,
  1051. BT_IO_OPT_INVALID);
  1052. if (!io) {
  1053. error("Can't listen at channel %d.", SAP_SERVER_CHANNEL);
  1054. g_error_free(gerr);
  1055. goto server_err;
  1056. }
  1057. server->listen_io = io;
  1058. if (!g_dbus_register_interface(btd_get_dbus_connection(),
  1059. adapter_get_path(server->adapter),
  1060. SAP_SERVER_INTERFACE,
  1061. server_methods, NULL,
  1062. server_properties, server,
  1063. destroy_sap_interface)) {
  1064. error("D-Bus failed to register %s interface",
  1065. SAP_SERVER_INTERFACE);
  1066. goto server_err;
  1067. }
  1068. DBG("server %p, listen socket 0x%02x", server,
  1069. g_io_channel_unix_get_fd(io));
  1070. return 0;
  1071. server_err:
  1072. server_remove(server);
  1073. sdp_err:
  1074. sap_exit();
  1075. return -1;
  1076. }
  1077. void sap_server_unregister(const char *path)
  1078. {
  1079. g_dbus_unregister_interface(btd_get_dbus_connection(),
  1080. path, SAP_SERVER_INTERFACE);
  1081. sap_exit();
  1082. }