gnunet-service-conversation.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2013, 2016, 2017 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file conversation/gnunet-service-conversation.c
  18. * @brief conversation service implementation
  19. * @author Simon Dieterle
  20. * @author Andreas Fuchs
  21. * @author Christian Grothoff
  22. */
  23. #include "platform.h"
  24. #include "gnunet_util_lib.h"
  25. #include "gnunet_protocols.h"
  26. #include "gnunet_applications.h"
  27. #include "gnunet_constants.h"
  28. #include "gnunet_signatures.h"
  29. #include "gnunet_cadet_service.h"
  30. #include "gnunet_conversation_service.h"
  31. #include "conversation.h"
  32. /**
  33. * How long is our signature on a call valid? Needs to be long enough for time zone
  34. * differences and network latency to not matter. No strong need for it to be short,
  35. * but we simply like all signatures to eventually expire.
  36. */
  37. #define RING_TIMEOUT GNUNET_TIME_UNIT_DAYS
  38. /**
  39. * A line connects a local client with a cadet channel (or, if it is an
  40. * open line, is waiting for a cadet channel).
  41. */
  42. struct Line;
  43. /**
  44. * The possible connection status
  45. */
  46. enum ChannelStatus
  47. {
  48. /**
  49. * We just got the connection, but no introduction yet.
  50. */
  51. CS_CALLEE_INIT,
  52. /**
  53. * Our phone is ringing, waiting for the client to pick up.
  54. */
  55. CS_CALLEE_RINGING,
  56. /**
  57. * We are talking!
  58. */
  59. CS_CALLEE_CONNECTED,
  60. /**
  61. * We're in shutdown, sending hangup messages before cleaning up.
  62. */
  63. CS_CALLEE_SHUTDOWN,
  64. /**
  65. * We are waiting for the phone to be picked up.
  66. */
  67. CS_CALLER_CALLING,
  68. /**
  69. * We are talking!
  70. */
  71. CS_CALLER_CONNECTED,
  72. /**
  73. * We're in shutdown, sending hangup messages before cleaning up.
  74. */
  75. CS_CALLER_SHUTDOWN
  76. };
  77. /**
  78. * A `struct Channel` represents a cadet channel, which is a P2P
  79. * connection to another conversation service. Multiple channels can
  80. * be attached the the same `struct Line`, which represents a local
  81. * client. We keep them in a linked list.
  82. */
  83. struct Channel
  84. {
  85. /**
  86. * This is a DLL.
  87. */
  88. struct Channel *next;
  89. /**
  90. * This is a DLL.
  91. */
  92. struct Channel *prev;
  93. /**
  94. * Line associated with the channel.
  95. */
  96. struct Line *line;
  97. /**
  98. * Handle for the channel.
  99. */
  100. struct GNUNET_CADET_Channel *channel;
  101. /**
  102. * Message queue for control messages
  103. */
  104. struct GNUNET_MQ_Handle *mq;
  105. /**
  106. * Temporary buffer for audio data in the @e mq.
  107. */
  108. struct GNUNET_MQ_Envelope *env;
  109. /**
  110. * Channel identifier we use for this call with the client.
  111. */
  112. uint32_t cid;
  113. /**
  114. * Current status of this line.
  115. */
  116. enum ChannelStatus status;
  117. /**
  118. * #GNUNET_YES if the channel was suspended by the other peer.
  119. */
  120. int8_t suspended_remote;
  121. /**
  122. * #GNUNET_YES if the channel was suspended by the local client.
  123. */
  124. int8_t suspended_local;
  125. };
  126. /**
  127. * A `struct Line` connects a local client with cadet channels.
  128. */
  129. struct Line
  130. {
  131. /**
  132. * This is a DLL.
  133. */
  134. struct Channel *channel_head;
  135. /**
  136. * This is a DLL.
  137. */
  138. struct Channel *channel_tail;
  139. /**
  140. * Handle to the line client.
  141. */
  142. struct GNUNET_SERVICE_Client *client;
  143. /**
  144. * Message queue for @e client.
  145. */
  146. struct GNUNET_MQ_Handle *mq;
  147. /**
  148. * Our open port.
  149. */
  150. struct GNUNET_CADET_Port *port;
  151. /**
  152. * Port number we are listening on (to verify signatures).
  153. * Only valid if @e port is non-NULL.
  154. */
  155. struct GNUNET_HashCode line_port;
  156. /**
  157. * Generator for channel IDs.
  158. */
  159. uint32_t cid_gen;
  160. };
  161. /**
  162. * Our configuration.
  163. */
  164. static const struct GNUNET_CONFIGURATION_Handle *cfg;
  165. /**
  166. * Handle for cadet
  167. */
  168. static struct GNUNET_CADET_Handle *cadet;
  169. /**
  170. * Identity of this peer.
  171. */
  172. static struct GNUNET_PeerIdentity my_identity;
  173. /**
  174. * Given a @a cid, find the corresponding channel given
  175. * a @a line.
  176. *
  177. * @param line a line to search
  178. * @param cid what to search for
  179. * @return NULL for not found
  180. */
  181. static struct Channel *
  182. find_channel_by_line (struct Line *line, uint32_t cid)
  183. {
  184. for (struct Channel *ch = line->channel_head; NULL != ch; ch = ch->next)
  185. if (cid == ch->cid)
  186. return ch;
  187. return NULL;
  188. }
  189. /**
  190. * Function to handle a pickup request message from the client
  191. *
  192. * @param cls the `struct Line` of the client from which the message is
  193. * @param msg the message from the client
  194. */
  195. static void
  196. handle_client_pickup_message (void *cls,
  197. const struct ClientPhonePickupMessage *msg)
  198. {
  199. struct Line *line = cls;
  200. struct CadetPhonePickupMessage *mppm;
  201. struct GNUNET_MQ_Envelope *env;
  202. struct Channel *ch;
  203. if (NULL == line->port)
  204. {
  205. /* we never opened the port, bad client! */
  206. GNUNET_break_op (0);
  207. GNUNET_SERVICE_client_drop (line->client);
  208. return;
  209. }
  210. for (ch = line->channel_head; NULL != ch; ch = ch->next)
  211. if (msg->cid == ch->cid)
  212. break;
  213. if (NULL == ch)
  214. {
  215. /* could have been destroyed asynchronously, ignore message */
  216. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
  217. GNUNET_SERVICE_client_continue (line->client);
  218. return;
  219. }
  220. switch (ch->status)
  221. {
  222. case CS_CALLEE_INIT:
  223. GNUNET_break (0);
  224. GNUNET_SERVICE_client_drop (line->client);
  225. return;
  226. case CS_CALLEE_RINGING:
  227. ch->status = CS_CALLEE_CONNECTED;
  228. break;
  229. case CS_CALLEE_CONNECTED:
  230. GNUNET_break (0);
  231. GNUNET_SERVICE_client_drop (line->client);
  232. return;
  233. case CS_CALLEE_SHUTDOWN:
  234. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  235. "Ignoring client's PICKUP message, line is in SHUTDOWN\n");
  236. break;
  237. case CS_CALLER_CALLING:
  238. case CS_CALLER_CONNECTED:
  239. case CS_CALLER_SHUTDOWN:
  240. GNUNET_break (0);
  241. GNUNET_SERVICE_client_drop (line->client);
  242. return;
  243. }
  244. GNUNET_break (CS_CALLEE_CONNECTED == ch->status);
  245. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending PICK_UP message to cadet\n");
  246. env =
  247. GNUNET_MQ_msg (mppm, GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_PICK_UP);
  248. GNUNET_MQ_send (ch->mq, env);
  249. GNUNET_SERVICE_client_continue (line->client);
  250. }
  251. /**
  252. * Channel went down, notify client and free data
  253. * structure.
  254. *
  255. * @param ch channel that went down
  256. */
  257. static void
  258. clean_up_channel (struct Channel *ch)
  259. {
  260. struct Line *line = ch->line;
  261. struct GNUNET_MQ_Envelope *env;
  262. struct ClientPhoneHangupMessage *hup;
  263. switch (ch->status)
  264. {
  265. case CS_CALLEE_INIT:
  266. case CS_CALLEE_SHUTDOWN:
  267. case CS_CALLER_SHUTDOWN:
  268. break;
  269. case CS_CALLEE_RINGING:
  270. case CS_CALLEE_CONNECTED:
  271. case CS_CALLER_CALLING:
  272. case CS_CALLER_CONNECTED:
  273. if (NULL != line)
  274. {
  275. env =
  276. GNUNET_MQ_msg (hup, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP);
  277. hup->cid = ch->cid;
  278. GNUNET_MQ_send (line->mq, env);
  279. }
  280. break;
  281. }
  282. if (NULL != line)
  283. GNUNET_CONTAINER_DLL_remove (line->channel_head, line->channel_tail, ch);
  284. GNUNET_free (ch);
  285. }
  286. /**
  287. * Destroy a channel.
  288. *
  289. * @param ch channel to destroy.
  290. */
  291. static void
  292. destroy_line_cadet_channels (struct Channel *ch)
  293. {
  294. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying cadet channels\n");
  295. if (NULL != ch->channel)
  296. {
  297. GNUNET_CADET_channel_destroy (ch->channel);
  298. ch->channel = NULL;
  299. }
  300. clean_up_channel (ch);
  301. }
  302. /**
  303. * We are done signalling shutdown to the other peer. Close down
  304. * the channel.
  305. *
  306. * @param cls the `struct Channel` to reset/terminate
  307. */
  308. static void
  309. mq_done_finish_caller_shutdown (void *cls)
  310. {
  311. struct Channel *ch = cls;
  312. switch (ch->status)
  313. {
  314. case CS_CALLEE_INIT:
  315. GNUNET_break (0);
  316. break;
  317. case CS_CALLEE_RINGING:
  318. GNUNET_break (0);
  319. break;
  320. case CS_CALLEE_CONNECTED:
  321. GNUNET_break (0);
  322. break;
  323. case CS_CALLEE_SHUTDOWN:
  324. destroy_line_cadet_channels (ch);
  325. break;
  326. case CS_CALLER_CALLING:
  327. GNUNET_break (0);
  328. break;
  329. case CS_CALLER_CONNECTED:
  330. GNUNET_break (0);
  331. break;
  332. case CS_CALLER_SHUTDOWN:
  333. destroy_line_cadet_channels (ch);
  334. break;
  335. }
  336. }
  337. /**
  338. * Function to handle a hangup request message from the client
  339. *
  340. * @param cls the `struct Line` the hangup is for
  341. * @param msg the message from the client
  342. */
  343. static void
  344. handle_client_hangup_message (void *cls,
  345. const struct ClientPhoneHangupMessage *msg)
  346. {
  347. struct Line *line = cls;
  348. struct GNUNET_MQ_Envelope *e;
  349. struct CadetPhoneHangupMessage *mhum;
  350. struct Channel *ch;
  351. for (ch = line->channel_head; NULL != ch; ch = ch->next)
  352. if (msg->cid == ch->cid)
  353. break;
  354. if (NULL == ch)
  355. {
  356. /* could have been destroyed asynchronously, ignore message */
  357. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
  358. GNUNET_SERVICE_client_continue (line->client);
  359. return;
  360. }
  361. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  362. "Received HANGUP for channel %u which is in state %d\n",
  363. msg->cid,
  364. ch->status);
  365. switch (ch->status)
  366. {
  367. case CS_CALLEE_INIT:
  368. GNUNET_break (0);
  369. GNUNET_SERVICE_client_drop (line->client);
  370. return;
  371. case CS_CALLEE_RINGING:
  372. ch->status = CS_CALLEE_SHUTDOWN;
  373. break;
  374. case CS_CALLEE_CONNECTED:
  375. ch->status = CS_CALLEE_SHUTDOWN;
  376. break;
  377. case CS_CALLEE_SHUTDOWN:
  378. /* maybe the other peer closed asynchronously... */
  379. GNUNET_SERVICE_client_continue (line->client);
  380. return;
  381. case CS_CALLER_CALLING:
  382. ch->status = CS_CALLER_SHUTDOWN;
  383. break;
  384. case CS_CALLER_CONNECTED:
  385. ch->status = CS_CALLER_SHUTDOWN;
  386. break;
  387. case CS_CALLER_SHUTDOWN:
  388. /* maybe the other peer closed asynchronously... */
  389. GNUNET_SERVICE_client_continue (line->client);
  390. return;
  391. }
  392. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HANG_UP message via cadet\n");
  393. e =
  394. GNUNET_MQ_msg (mhum, GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_HANG_UP);
  395. GNUNET_MQ_notify_sent (e, &mq_done_finish_caller_shutdown, ch);
  396. GNUNET_MQ_send (ch->mq, e);
  397. GNUNET_SERVICE_client_continue (line->client);
  398. }
  399. /**
  400. * Function to handle a suspend request message from the client
  401. *
  402. * @param cls the `struct Line` the message is about
  403. * @param msg the message from the client
  404. */
  405. static void
  406. handle_client_suspend_message (void *cls,
  407. const struct ClientPhoneSuspendMessage *msg)
  408. {
  409. struct Line *line = cls;
  410. struct GNUNET_MQ_Envelope *e;
  411. struct CadetPhoneSuspendMessage *mhum;
  412. struct Channel *ch;
  413. for (ch = line->channel_head; NULL != ch; ch = ch->next)
  414. if (msg->cid == ch->cid)
  415. break;
  416. if (NULL == ch)
  417. {
  418. /* could have been destroyed asynchronously, ignore message */
  419. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
  420. GNUNET_SERVICE_client_continue (line->client);
  421. return;
  422. }
  423. if (GNUNET_YES == ch->suspended_local)
  424. {
  425. GNUNET_break (0);
  426. GNUNET_SERVICE_client_drop (line->client);
  427. return;
  428. }
  429. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  430. "Received SUSPEND for channel %u which is in state %d\n",
  431. msg->cid,
  432. ch->status);
  433. switch (ch->status)
  434. {
  435. case CS_CALLEE_INIT:
  436. GNUNET_break (0);
  437. GNUNET_SERVICE_client_drop (line->client);
  438. return;
  439. case CS_CALLEE_RINGING:
  440. GNUNET_break (0);
  441. GNUNET_SERVICE_client_drop (line->client);
  442. return;
  443. case CS_CALLEE_CONNECTED:
  444. ch->suspended_local = GNUNET_YES;
  445. break;
  446. case CS_CALLEE_SHUTDOWN:
  447. /* maybe the other peer closed asynchronously... */
  448. GNUNET_SERVICE_client_continue (line->client);
  449. return;
  450. case CS_CALLER_CALLING:
  451. GNUNET_break (0);
  452. GNUNET_SERVICE_client_drop (line->client);
  453. return;
  454. case CS_CALLER_CONNECTED:
  455. ch->suspended_local = GNUNET_YES;
  456. break;
  457. case CS_CALLER_SHUTDOWN:
  458. /* maybe the other peer closed asynchronously... */
  459. GNUNET_SERVICE_client_continue (line->client);
  460. return;
  461. }
  462. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUSPEND message via cadet\n");
  463. e =
  464. GNUNET_MQ_msg (mhum, GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_SUSPEND);
  465. GNUNET_MQ_send (ch->mq, e);
  466. GNUNET_SERVICE_client_continue (line->client);
  467. }
  468. /**
  469. * Function to handle a resume request message from the client
  470. *
  471. * @param cls the `struct Line` the message is about
  472. * @param msg the message from the client
  473. */
  474. static void
  475. handle_client_resume_message (void *cls,
  476. const struct ClientPhoneResumeMessage *msg)
  477. {
  478. struct Line *line = cls;
  479. struct GNUNET_MQ_Envelope *e;
  480. struct CadetPhoneResumeMessage *mhum;
  481. struct Channel *ch;
  482. for (ch = line->channel_head; NULL != ch; ch = ch->next)
  483. if (msg->cid == ch->cid)
  484. break;
  485. if (NULL == ch)
  486. {
  487. /* could have been destroyed asynchronously, ignore message */
  488. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
  489. GNUNET_SERVICE_client_continue (line->client);
  490. return;
  491. }
  492. if (GNUNET_YES != ch->suspended_local)
  493. {
  494. GNUNET_break (0);
  495. GNUNET_SERVICE_client_drop (line->client);
  496. return;
  497. }
  498. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  499. "Received RESUME for channel %u which is in state %d\n",
  500. msg->cid,
  501. ch->status);
  502. switch (ch->status)
  503. {
  504. case CS_CALLEE_INIT:
  505. GNUNET_break (0);
  506. GNUNET_SERVICE_client_drop (line->client);
  507. return;
  508. case CS_CALLEE_RINGING:
  509. GNUNET_break (0);
  510. GNUNET_SERVICE_client_drop (line->client);
  511. return;
  512. case CS_CALLEE_CONNECTED:
  513. ch->suspended_local = GNUNET_NO;
  514. break;
  515. case CS_CALLEE_SHUTDOWN:
  516. /* maybe the other peer closed asynchronously... */
  517. GNUNET_SERVICE_client_continue (line->client);
  518. return;
  519. case CS_CALLER_CALLING:
  520. GNUNET_break (0);
  521. GNUNET_SERVICE_client_drop (line->client);
  522. return;
  523. case CS_CALLER_CONNECTED:
  524. ch->suspended_local = GNUNET_NO;
  525. break;
  526. case CS_CALLER_SHUTDOWN:
  527. /* maybe the other peer closed asynchronously... */
  528. GNUNET_SERVICE_client_drop (line->client);
  529. return;
  530. }
  531. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RESUME message via cadet\n");
  532. e = GNUNET_MQ_msg (mhum, GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RESUME);
  533. GNUNET_MQ_send (ch->mq, e);
  534. GNUNET_SERVICE_client_continue (line->client);
  535. }
  536. /**
  537. * Transmission of audio data via cadet channel finished.
  538. *
  539. * @param cls the `struct Channel` we are transmitting for
  540. */
  541. static void
  542. channel_audio_sent_notify (void *cls)
  543. {
  544. struct Channel *ch = cls;
  545. ch->env = NULL;
  546. }
  547. /**
  548. * Function to check audio data from the client
  549. *
  550. * @param cls the `struct Line` the message is about
  551. * @param msg the message from the client
  552. * @return #GNUNET_OK (any data is ok)
  553. */
  554. static int
  555. check_client_audio_message (void *cls, const struct ClientAudioMessage *msg)
  556. {
  557. (void) cls;
  558. (void) msg;
  559. return GNUNET_OK;
  560. }
  561. /**
  562. * Function to handle audio data from the client
  563. *
  564. * @param cls the `struct Line` the message is about
  565. * @param msg the message from the client
  566. */
  567. static void
  568. handle_client_audio_message (void *cls, const struct ClientAudioMessage *msg)
  569. {
  570. struct Line *line = cls;
  571. struct CadetAudioMessage *mam;
  572. struct Channel *ch;
  573. size_t size;
  574. size = ntohs (msg->header.size) - sizeof(struct ClientAudioMessage);
  575. ch = find_channel_by_line (line, msg->cid);
  576. if (NULL == ch)
  577. {
  578. /* could have been destroyed asynchronously, ignore message */
  579. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %u not found\n", msg->cid);
  580. GNUNET_SERVICE_client_continue (line->client);
  581. return;
  582. }
  583. switch (ch->status)
  584. {
  585. case CS_CALLEE_INIT:
  586. case CS_CALLEE_RINGING:
  587. case CS_CALLER_CALLING:
  588. GNUNET_break (0);
  589. GNUNET_SERVICE_client_drop (line->client);
  590. return;
  591. case CS_CALLEE_CONNECTED:
  592. case CS_CALLER_CONNECTED:
  593. /* common case, handled below */
  594. break;
  595. case CS_CALLEE_SHUTDOWN:
  596. case CS_CALLER_SHUTDOWN:
  597. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
  598. "Cadet audio channel in shutdown; audio data dropped\n");
  599. GNUNET_SERVICE_client_continue (line->client);
  600. return;
  601. }
  602. if (GNUNET_YES == ch->suspended_local)
  603. {
  604. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  605. "This channel is suspended locally\n");
  606. GNUNET_SERVICE_client_drop (line->client);
  607. return;
  608. }
  609. if (NULL != ch->env)
  610. {
  611. /* NOTE: we may want to not do this and instead combine the data */
  612. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  613. "Bandwidth insufficient; dropping previous audio data segment\n");
  614. GNUNET_MQ_send_cancel (ch->env);
  615. ch->env = NULL;
  616. }
  617. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  618. "Received %u bytes of AUDIO data from client CID %u\n",
  619. (unsigned int) size,
  620. msg->cid);
  621. ch->env = GNUNET_MQ_msg_extra (mam,
  622. size,
  623. GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_AUDIO);
  624. GNUNET_memcpy (&mam[1], &msg[1], size);
  625. /* FIXME: set options for unreliable transmission */
  626. GNUNET_MQ_notify_sent (ch->env, &channel_audio_sent_notify, ch);
  627. GNUNET_MQ_send (ch->mq, ch->env);
  628. GNUNET_SERVICE_client_continue (line->client);
  629. }
  630. /**
  631. * Function to handle a ring message incoming over cadet
  632. *
  633. * @param cls closure, NULL
  634. * @param msg the incoming message
  635. */
  636. static void
  637. handle_cadet_ring_message (void *cls, const struct CadetPhoneRingMessage *msg)
  638. {
  639. struct Channel *ch = cls;
  640. struct Line *line = ch->line;
  641. struct GNUNET_MQ_Envelope *env;
  642. struct ClientPhoneRingMessage *cring;
  643. struct CadetPhoneRingInfoPS rs;
  644. rs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING);
  645. rs.purpose.size = htonl (sizeof(struct CadetPhoneRingInfoPS));
  646. rs.line_port = line->line_port;
  647. rs.target_peer = my_identity;
  648. rs.expiration_time = msg->expiration_time;
  649. if (GNUNET_OK !=
  650. GNUNET_IDENTITY_signature_verify (
  651. GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING,
  652. &rs,
  653. &msg->signature,
  654. &msg->caller_id))
  655. {
  656. GNUNET_break_op (0);
  657. destroy_line_cadet_channels (ch);
  658. return;
  659. }
  660. if (0 == GNUNET_TIME_absolute_get_remaining (
  661. GNUNET_TIME_absolute_ntoh (msg->expiration_time))
  662. .rel_value_us)
  663. {
  664. /* ancient call, replay? */
  665. GNUNET_break_op (0);
  666. /* Note that our reliance on time here is awkward; better would be
  667. to use a more complex challenge-response protocol against
  668. replay attacks. Left for future work ;-). */
  669. destroy_line_cadet_channels (ch);
  670. return;
  671. }
  672. if (CS_CALLEE_INIT != ch->status)
  673. {
  674. GNUNET_break_op (0);
  675. destroy_line_cadet_channels (ch);
  676. return;
  677. }
  678. GNUNET_CADET_receive_done (ch->channel);
  679. ch->status = CS_CALLEE_RINGING;
  680. env = GNUNET_MQ_msg (cring, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING);
  681. cring->cid = ch->cid;
  682. cring->caller_id = msg->caller_id;
  683. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  684. "Sending RING message to client. CID is %u\n",
  685. (unsigned int) ch->cid);
  686. GNUNET_MQ_send (line->mq, env);
  687. }
  688. /**
  689. * Function to handle a hangup message incoming over cadet
  690. *
  691. * @param cls closure, our `struct Channel *`
  692. * @param message the incoming message
  693. */
  694. static void
  695. handle_cadet_hangup_message (void *cls,
  696. const struct CadetPhoneHangupMessage *message)
  697. {
  698. struct Channel *ch = cls;
  699. struct Line *line = ch->line;
  700. struct GNUNET_MQ_Envelope *env;
  701. struct ClientPhoneHangupMessage *hup;
  702. enum ChannelStatus status;
  703. uint32_t cid;
  704. (void) message;
  705. GNUNET_CADET_receive_done (ch->channel);
  706. cid = ch->cid;
  707. status = ch->status;
  708. destroy_line_cadet_channels (ch);
  709. switch (status)
  710. {
  711. case CS_CALLEE_INIT:
  712. GNUNET_break_op (0);
  713. return;
  714. case CS_CALLEE_RINGING:
  715. case CS_CALLEE_CONNECTED:
  716. break;
  717. case CS_CALLEE_SHUTDOWN:
  718. return;
  719. case CS_CALLER_CALLING:
  720. case CS_CALLER_CONNECTED:
  721. break;
  722. case CS_CALLER_SHUTDOWN:
  723. return;
  724. }
  725. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HANG UP message to client\n");
  726. env = GNUNET_MQ_msg (hup, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP);
  727. hup->cid = cid;
  728. GNUNET_MQ_send (line->mq, env);
  729. }
  730. /**
  731. * Function to handle a pickup message incoming over cadet
  732. *
  733. * @param cls closure, our `struct Channel *`
  734. * @param message the incoming message
  735. */
  736. static void
  737. handle_cadet_pickup_message (void *cls,
  738. const struct CadetPhonePickupMessage *message)
  739. {
  740. struct Channel *ch = cls;
  741. struct Line *line = ch->line;
  742. struct GNUNET_MQ_Envelope *env;
  743. struct ClientPhonePickedupMessage *pick;
  744. (void) message;
  745. GNUNET_CADET_receive_done (ch->channel);
  746. switch (ch->status)
  747. {
  748. case CS_CALLEE_INIT:
  749. case CS_CALLEE_RINGING:
  750. case CS_CALLEE_CONNECTED:
  751. GNUNET_break_op (0);
  752. destroy_line_cadet_channels (ch);
  753. return;
  754. case CS_CALLEE_SHUTDOWN:
  755. GNUNET_break_op (0);
  756. destroy_line_cadet_channels (ch);
  757. return;
  758. case CS_CALLER_CALLING:
  759. ch->status = CS_CALLER_CONNECTED;
  760. break;
  761. case CS_CALLER_CONNECTED:
  762. GNUNET_break_op (0);
  763. return;
  764. case CS_CALLER_SHUTDOWN:
  765. GNUNET_break_op (0);
  766. mq_done_finish_caller_shutdown (ch);
  767. return;
  768. }
  769. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending PICKED UP message to client\n");
  770. env =
  771. GNUNET_MQ_msg (pick, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP);
  772. pick->cid = ch->cid;
  773. GNUNET_MQ_send (line->mq, env);
  774. }
  775. /**
  776. * Function to handle a suspend message incoming over cadet
  777. *
  778. * @param cls closure, our `struct Channel *`
  779. * @param message the incoming message
  780. */
  781. static void
  782. handle_cadet_suspend_message (void *cls,
  783. const struct CadetPhoneSuspendMessage *message)
  784. {
  785. struct Channel *ch = cls;
  786. struct Line *line = ch->line;
  787. struct GNUNET_MQ_Envelope *env;
  788. struct ClientPhoneSuspendMessage *suspend;
  789. (void) message;
  790. GNUNET_CADET_receive_done (ch->channel);
  791. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suspending channel CID: %u\n", ch->cid);
  792. switch (ch->status)
  793. {
  794. case CS_CALLEE_INIT:
  795. GNUNET_break_op (0);
  796. break;
  797. case CS_CALLEE_RINGING:
  798. GNUNET_break_op (0);
  799. break;
  800. case CS_CALLEE_CONNECTED:
  801. ch->suspended_remote = GNUNET_YES;
  802. break;
  803. case CS_CALLEE_SHUTDOWN:
  804. return;
  805. case CS_CALLER_CALLING:
  806. GNUNET_break_op (0);
  807. break;
  808. case CS_CALLER_CONNECTED:
  809. ch->suspended_remote = GNUNET_YES;
  810. break;
  811. case CS_CALLER_SHUTDOWN:
  812. return;
  813. }
  814. env =
  815. GNUNET_MQ_msg (suspend, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND);
  816. suspend->cid = ch->cid;
  817. GNUNET_MQ_send (line->mq, env);
  818. }
  819. /**
  820. * Function to handle a resume message incoming over cadet
  821. *
  822. * @param cls closure, our `struct Channel *`
  823. * @param msg the incoming message
  824. */
  825. static void
  826. handle_cadet_resume_message (void *cls,
  827. const struct CadetPhoneResumeMessage *msg)
  828. {
  829. struct Channel *ch = cls;
  830. struct Line *line;
  831. struct GNUNET_MQ_Envelope *env;
  832. struct ClientPhoneResumeMessage *resume;
  833. (void) msg;
  834. line = ch->line;
  835. GNUNET_CADET_receive_done (ch->channel);
  836. if (GNUNET_YES != ch->suspended_remote)
  837. {
  838. GNUNET_log (
  839. GNUNET_ERROR_TYPE_DEBUG,
  840. "RESUME message received for non-suspended channel, dropping channel.\n");
  841. destroy_line_cadet_channels (ch);
  842. return;
  843. }
  844. switch (ch->status)
  845. {
  846. case CS_CALLEE_INIT:
  847. GNUNET_break (0);
  848. break;
  849. case CS_CALLEE_RINGING:
  850. GNUNET_break (0);
  851. break;
  852. case CS_CALLEE_CONNECTED:
  853. ch->suspended_remote = GNUNET_NO;
  854. break;
  855. case CS_CALLEE_SHUTDOWN:
  856. return;
  857. case CS_CALLER_CALLING:
  858. GNUNET_break (0);
  859. break;
  860. case CS_CALLER_CONNECTED:
  861. ch->suspended_remote = GNUNET_NO;
  862. break;
  863. case CS_CALLER_SHUTDOWN:
  864. return;
  865. }
  866. env =
  867. GNUNET_MQ_msg (resume, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME);
  868. resume->cid = ch->cid;
  869. GNUNET_MQ_send (line->mq, env);
  870. }
  871. /**
  872. * Function to check an audio message incoming over cadet
  873. *
  874. * @param cls closure, our `struct Channel *`
  875. * @param msg the incoming message
  876. * @return #GNUNET_OK (always)
  877. */
  878. static int
  879. check_cadet_audio_message (void *cls, const struct CadetAudioMessage *msg)
  880. {
  881. (void) cls;
  882. (void) msg;
  883. return GNUNET_OK; /* any payload is fine */
  884. }
  885. /**
  886. * Function to handle an audio message incoming over cadet
  887. *
  888. * @param cls closure, our `struct Channel *`
  889. * @param msg the incoming message
  890. */
  891. static void
  892. handle_cadet_audio_message (void *cls, const struct CadetAudioMessage *msg)
  893. {
  894. struct Channel *ch = cls;
  895. size_t msize = ntohs (msg->header.size) - sizeof(struct CadetAudioMessage);
  896. struct GNUNET_MQ_Envelope *env;
  897. struct ClientAudioMessage *cam;
  898. GNUNET_CADET_receive_done (ch->channel);
  899. if ((GNUNET_YES == ch->suspended_local) ||
  900. (GNUNET_YES == ch->suspended_remote))
  901. {
  902. GNUNET_log (
  903. GNUNET_ERROR_TYPE_DEBUG,
  904. "Received %u bytes of AUDIO data on suspended channel CID %u; dropping\n",
  905. (unsigned int) msize,
  906. ch->cid);
  907. return;
  908. }
  909. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  910. "Forwarding %u bytes of AUDIO data to client CID %u\n",
  911. (unsigned int) msize,
  912. ch->cid);
  913. env =
  914. GNUNET_MQ_msg_extra (cam, msize, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO);
  915. cam->cid = ch->cid;
  916. GNUNET_memcpy (&cam[1], &msg[1], msize);
  917. GNUNET_MQ_send (ch->line->mq, env);
  918. }
  919. /**
  920. * Function called whenever an inbound channel is destroyed. Should clean up
  921. * any associated state.
  922. *
  923. * @param cls closure (set from #GNUNET_CADET_connect)
  924. * @param channel connection to the other end (henceforth invalid)
  925. */
  926. static void
  927. inbound_end (void *cls, const struct GNUNET_CADET_Channel *channel)
  928. {
  929. struct Channel *ch = cls;
  930. GNUNET_assert (channel == ch->channel);
  931. ch->channel = NULL;
  932. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  933. "Channel destroyed by CADET in state %d\n",
  934. ch->status);
  935. clean_up_channel (ch);
  936. }
  937. /**
  938. * Function to handle call request from the client
  939. *
  940. * @param cls the `struct Line` the message is about
  941. * @param msg the message from the client
  942. */
  943. static void
  944. handle_client_call_message (void *cls, const struct ClientCallMessage *msg)
  945. {
  946. struct Line *line = cls;
  947. struct Channel *ch = GNUNET_new (struct Channel);
  948. struct GNUNET_MQ_MessageHandler cadet_handlers[] =
  949. { GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
  950. GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_HANG_UP,
  951. struct CadetPhoneHangupMessage,
  952. ch),
  953. GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
  954. GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_PICK_UP,
  955. struct CadetPhonePickupMessage,
  956. ch),
  957. GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
  958. GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_SUSPEND,
  959. struct CadetPhoneSuspendMessage,
  960. ch),
  961. GNUNET_MQ_hd_fixed_size (cadet_resume_message,
  962. GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RESUME,
  963. struct CadetPhoneResumeMessage,
  964. ch),
  965. GNUNET_MQ_hd_var_size (cadet_audio_message,
  966. GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_AUDIO,
  967. struct CadetAudioMessage,
  968. ch),
  969. GNUNET_MQ_handler_end () };
  970. struct GNUNET_MQ_Envelope *e;
  971. struct CadetPhoneRingMessage *ring;
  972. struct CadetPhoneRingInfoPS rs;
  973. line->line_port = msg->line_port;
  974. rs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING);
  975. rs.purpose.size = htonl (sizeof(struct CadetPhoneRingInfoPS));
  976. rs.line_port = line->line_port;
  977. rs.target_peer = msg->target;
  978. rs.expiration_time =
  979. GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (RING_TIMEOUT));
  980. ch->line = line;
  981. GNUNET_CONTAINER_DLL_insert (line->channel_head, line->channel_tail, ch);
  982. ch->status = CS_CALLER_CALLING;
  983. ch->channel = GNUNET_CADET_channel_create (cadet,
  984. ch,
  985. &msg->target,
  986. &msg->line_port,
  987. NULL,
  988. &inbound_end,
  989. cadet_handlers);
  990. ch->mq = GNUNET_CADET_get_mq (ch->channel);
  991. e = GNUNET_MQ_msg (ring, GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING);
  992. GNUNET_IDENTITY_key_get_public (&msg->caller_id, &ring->caller_id);
  993. ring->expiration_time = rs.expiration_time;
  994. GNUNET_IDENTITY_sign (&msg->caller_id, &rs, &ring->signature);
  995. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message via CADET\n");
  996. GNUNET_MQ_send (ch->mq, e);
  997. GNUNET_SERVICE_client_continue (line->client);
  998. }
  999. /**
  1000. * Method called whenever another peer has added us to a channel
  1001. * the other peer initiated.
  1002. *
  1003. * @param cls the `struct Line` receiving a connection
  1004. * @param channel new handle to the channel
  1005. * @param initiator peer that started the channel
  1006. * @return initial channel context for the channel
  1007. */
  1008. static void *
  1009. inbound_channel (void *cls,
  1010. struct GNUNET_CADET_Channel *channel,
  1011. const struct GNUNET_PeerIdentity *initiator)
  1012. {
  1013. struct Line *line = cls;
  1014. struct Channel *ch;
  1015. (void) initiator;
  1016. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  1017. "Received incoming cadet channel on line %p\n",
  1018. line);
  1019. ch = GNUNET_new (struct Channel);
  1020. ch->status = CS_CALLEE_INIT;
  1021. ch->line = line;
  1022. ch->channel = channel;
  1023. ch->mq = GNUNET_CADET_get_mq (ch->channel);
  1024. ch->cid = line->cid_gen++;
  1025. GNUNET_CONTAINER_DLL_insert (line->channel_head, line->channel_tail, ch);
  1026. return ch;
  1027. }
  1028. /**
  1029. * A client connected. Initialize the `struct Line` data structure.
  1030. *
  1031. * @param cls closure, NULL
  1032. * @param client identification of the client
  1033. * @param mq message queue for @a client
  1034. * @return the `struct Line` for the client
  1035. */
  1036. static void *
  1037. client_connect_cb (void *cls,
  1038. struct GNUNET_SERVICE_Client *client,
  1039. struct GNUNET_MQ_Handle *mq)
  1040. {
  1041. struct Line *line;
  1042. (void) cls;
  1043. line = GNUNET_new (struct Line);
  1044. line->client = client;
  1045. line->mq = mq;
  1046. return line;
  1047. }
  1048. /**
  1049. * A client disconnected. Remove all of its data structure entries.
  1050. *
  1051. * @param cls closure, NULL
  1052. * @param client identification of the client
  1053. * @param app_ctx our `struct Line *` for @a client
  1054. */
  1055. static void
  1056. client_disconnect_cb (void *cls,
  1057. struct GNUNET_SERVICE_Client *client,
  1058. void *app_ctx)
  1059. {
  1060. struct Line *line = app_ctx;
  1061. struct Channel *chn;
  1062. (void) cls;
  1063. (void) client;
  1064. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected, closing line\n");
  1065. if (NULL != line->port)
  1066. {
  1067. GNUNET_CADET_close_port (line->port);
  1068. line->port = NULL;
  1069. }
  1070. for (struct Channel *ch = line->channel_head; NULL != ch; ch = chn)
  1071. {
  1072. chn = ch->next;
  1073. ch->line = NULL;
  1074. destroy_line_cadet_channels (ch);
  1075. }
  1076. GNUNET_free (line);
  1077. }
  1078. /**
  1079. * Function to register a phone.
  1080. *
  1081. * @param cls the `struct Line` of the client from which the message is
  1082. * @param msg the message from the client
  1083. */
  1084. static void
  1085. handle_client_register_message (void *cls,
  1086. const struct ClientPhoneRegisterMessage *msg)
  1087. {
  1088. struct Line *line = cls;
  1089. struct GNUNET_MQ_MessageHandler cadet_handlers[] =
  1090. { GNUNET_MQ_hd_fixed_size (cadet_ring_message,
  1091. GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING,
  1092. struct CadetPhoneRingMessage,
  1093. NULL),
  1094. GNUNET_MQ_hd_fixed_size (cadet_hangup_message,
  1095. GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_HANG_UP,
  1096. struct CadetPhoneHangupMessage,
  1097. NULL),
  1098. GNUNET_MQ_hd_fixed_size (cadet_pickup_message,
  1099. GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_PICK_UP,
  1100. struct CadetPhonePickupMessage,
  1101. NULL),
  1102. GNUNET_MQ_hd_fixed_size (cadet_suspend_message,
  1103. GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_SUSPEND,
  1104. struct CadetPhoneSuspendMessage,
  1105. NULL),
  1106. GNUNET_MQ_hd_fixed_size (cadet_resume_message,
  1107. GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RESUME,
  1108. struct CadetPhoneResumeMessage,
  1109. NULL),
  1110. GNUNET_MQ_hd_var_size (cadet_audio_message,
  1111. GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_AUDIO,
  1112. struct CadetAudioMessage,
  1113. NULL),
  1114. GNUNET_MQ_handler_end () };
  1115. line->line_port = msg->line_port;
  1116. line->port = GNUNET_CADET_open_port (cadet,
  1117. &msg->line_port,
  1118. &inbound_channel,
  1119. line,
  1120. NULL,
  1121. &inbound_end,
  1122. cadet_handlers);
  1123. if (NULL == line->port)
  1124. {
  1125. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  1126. _ ("Could not open line, port %s already in use!\n"),
  1127. GNUNET_h2s (&msg->line_port));
  1128. GNUNET_SERVICE_client_drop (line->client);
  1129. return;
  1130. }
  1131. GNUNET_SERVICE_client_continue (line->client);
  1132. }
  1133. /**
  1134. * Shutdown nicely
  1135. *
  1136. * @param cls closure, NULL
  1137. */
  1138. static void
  1139. do_shutdown (void *cls)
  1140. {
  1141. (void) cls;
  1142. if (NULL != cadet)
  1143. {
  1144. GNUNET_CADET_disconnect (cadet);
  1145. cadet = NULL;
  1146. }
  1147. }
  1148. /**
  1149. * Main function that will be run by the scheduler.
  1150. *
  1151. * @param cls closure
  1152. * @param c configuration
  1153. * @param service service handle
  1154. */
  1155. static void
  1156. run (void *cls,
  1157. const struct GNUNET_CONFIGURATION_Handle *c,
  1158. struct GNUNET_SERVICE_Handle *service)
  1159. {
  1160. (void) cls;
  1161. (void) service;
  1162. cfg = c;
  1163. GNUNET_assert (GNUNET_OK ==
  1164. GNUNET_CRYPTO_get_peer_identity (cfg, &my_identity));
  1165. cadet = GNUNET_CADET_connect (cfg);
  1166. if (NULL == cadet)
  1167. {
  1168. GNUNET_break (0);
  1169. GNUNET_SCHEDULER_shutdown ();
  1170. return;
  1171. }
  1172. GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
  1173. }
  1174. /**
  1175. * Define "main" method using service macro.
  1176. */
  1177. GNUNET_SERVICE_MAIN (
  1178. "conversation",
  1179. GNUNET_SERVICE_OPTION_NONE,
  1180. &run,
  1181. &client_connect_cb,
  1182. &client_disconnect_cb,
  1183. NULL,
  1184. GNUNET_MQ_hd_fixed_size (client_register_message,
  1185. GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_REGISTER,
  1186. struct ClientPhoneRegisterMessage,
  1187. NULL),
  1188. GNUNET_MQ_hd_fixed_size (client_pickup_message,
  1189. GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICK_UP,
  1190. struct ClientPhonePickupMessage,
  1191. NULL),
  1192. GNUNET_MQ_hd_fixed_size (client_suspend_message,
  1193. GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND,
  1194. struct ClientPhoneSuspendMessage,
  1195. NULL),
  1196. GNUNET_MQ_hd_fixed_size (client_resume_message,
  1197. GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME,
  1198. struct ClientPhoneResumeMessage,
  1199. NULL),
  1200. GNUNET_MQ_hd_fixed_size (client_hangup_message,
  1201. GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP,
  1202. struct ClientPhoneHangupMessage,
  1203. NULL),
  1204. GNUNET_MQ_hd_fixed_size (client_call_message,
  1205. GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_CALL,
  1206. struct ClientCallMessage,
  1207. NULL),
  1208. GNUNET_MQ_hd_var_size (client_audio_message,
  1209. GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO,
  1210. struct ClientAudioMessage,
  1211. NULL),
  1212. GNUNET_MQ_handler_end ());
  1213. /* end of gnunet-service-conversation.c */