Advertisement
Guest User

baresip sip client

a guest
May 15th, 2015
893
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.25 KB | None | 0 0
  1. /**
  2.  * @file sip_ua.c SIP User Agent Demo
  3.  *
  4.  *
  5.  *  To test inbound calls, invoke without arguments. sip_ua will
  6.  *  register and wait for an inbound call:
  7.  *
  8.  *  $ ./sip_ua
  9.  *
  10.  *
  11.  *  To test otbound calls, invoke with a SIP URI argument.
  12.  *  sip_will will invite provided URI:
  13.  *
  14.  *  $ ./sip_ua sip:echo@creytiv.com
  15.  *
  16.  *
  17.  * Copyright (C) 2011 Creytiv.com
  18.  */
  19.  
  20. #include <string.h>
  21. #include <re.h>
  22.  
  23.  
  24. static struct sipsess_sock *sess_sock;  /* SIP session socket */
  25. static struct sdp_session *sdp;         /* SDP session        */
  26. static struct sdp_media *sdp_media;     /* SDP media          */
  27. static struct sipsess *sess;            /* SIP session        */
  28. static struct sipreg *reg;              /* SIP registration   */
  29. static struct sip *sip;                 /* SIP stack          */
  30.  
  31. const char *registrar  = "sip:creytiv.com";
  32. const char *uri  = "sip:demo@creytiv.com";
  33. const char *name = "demo";
  34.  
  35.  
  36. /* terminate */
  37. static void terminate(void)
  38. {
  39.     /* terminate session */
  40.     sess = mem_deref(sess);
  41.  
  42.     /* terminate registration */
  43.     reg = mem_deref(reg);
  44.  
  45.     /* wait for pending transactions to finish */
  46.     sip_close(sip, false);
  47. }
  48.  
  49.  
  50. /* called when challenged for credentials */
  51. static int auth_handler(char **user, char **pass, const char *realm, void *arg)
  52. {
  53.     int err = 0;
  54.     (void)realm;
  55.     (void)arg;
  56.  
  57.     err |= str_dup(user, "demo");
  58.     err |= str_dup(pass, "secret");
  59.  
  60.     return err;
  61. }
  62.  
  63.  
  64. /* print SDP status */
  65. static void update_media(void)
  66. {
  67.     const struct sdp_format *fmt;
  68.  
  69.     re_printf("SDP peer address: %J\n", sdp_media_raddr(sdp_media));
  70.  
  71.     fmt = sdp_media_rformat(sdp_media, NULL);
  72.     if (!fmt) {
  73.         re_printf("no common media format found\n");
  74.         return;
  75.     }
  76.  
  77.     re_printf("SDP media format: %s/%u/%u (payload type: %u)\n",
  78.           fmt->name, fmt->srate, fmt->ch, fmt->pt);
  79. }
  80.  
  81.  
  82. /*
  83.  * called when an SDP offer is received (got offer: true) or
  84.  * when an offer is to be sent (got_offer: false)
  85.  */
  86. static int offer_handler(struct mbuf **mbp, const struct sip_msg *msg,
  87.              void *arg)
  88. {
  89.     const bool got_offer = mbuf_get_left(msg->mb);
  90.     int err;
  91.     (void)arg;
  92.  
  93.     if (got_offer) {
  94.  
  95.         err = sdp_decode(sdp, msg->mb, true);
  96.         if (err) {
  97.             re_fprintf(stderr, "unable to decode SDP offer: %s\n",
  98.                    strerror(err));
  99.             return err;
  100.         }
  101.  
  102.         re_printf("SDP offer received\n");
  103.         update_media();
  104.     }
  105.     else {
  106.         re_printf("sending SDP offer\n");
  107.     }
  108.  
  109.     return sdp_encode(mbp, sdp, !got_offer);
  110. }
  111.  
  112.  
  113. /* called when an SDP answer is received */
  114. static int answer_handler(const struct sip_msg *msg, void *arg)
  115. {
  116.     int err;
  117.     (void)arg;
  118.  
  119.     re_printf("SDP answer received\n");
  120.  
  121.     err = sdp_decode(sdp, msg->mb, false);
  122.     if (err) {
  123.         re_fprintf(stderr, "unable to decode SDP answer: %s\n",
  124.                strerror(err));
  125.         return err;
  126.     }
  127.  
  128.     update_media();
  129.  
  130.     return 0;
  131. }
  132.  
  133.  
  134. /* called when SIP progress (like 180 Ringing) responses are received */
  135. static void progress_handler(const struct sip_msg *msg, void *arg)
  136. {
  137.     (void)arg;
  138.  
  139.     re_printf("session progress: %u %r\n", msg->scode, &msg->reason);
  140. }
  141.  
  142.  
  143. /* called when the session is established */
  144. static void establish_handler(const struct sip_msg *msg, void *arg)
  145. {
  146.     (void)msg;
  147.     (void)arg;
  148.  
  149.     re_printf("session established\n");
  150. }
  151.  
  152.  
  153. /* called when the session fails to connect or is terminated from peer */
  154. static void close_handler(int err, const struct sip_msg *msg, void *arg)
  155. {
  156.     (void)arg;
  157.  
  158.     if (err)
  159.         re_printf("session closed: %s\n", strerror(err));
  160.     else
  161.         re_printf("session closed: %u %r\n", msg->scode, &msg->reason);
  162.  
  163.     terminate();
  164. }
  165.  
  166.  
  167. /* called upon incoming calls */
  168. static void connect_handler(const struct sip_msg *msg, void *arg)
  169. {
  170.     struct mbuf *mb;
  171.     bool got_offer;
  172.     int err;
  173.     (void)arg;
  174.  
  175.     if (sess) {
  176.         /* Already in a call */
  177.         (void)sip_treply(NULL, sip, msg, 486, "Busy Here");
  178.         return;
  179.     }
  180.    
  181.     if(!pl_strcmp(&msg->from.uri.user,"your_caller_id")){
  182.         (void)sip_treply(NULL, sip, msg, 486, "Busy Here");
  183.          return;
  184.     }
  185.    
  186.  
  187.     got_offer = (mbuf_get_left(msg->mb) > 0);
  188.  
  189.     /* Decode SDP offer if incoming INVITE contains SDP */
  190.     if (got_offer) {
  191.  
  192.         err = sdp_decode(sdp, msg->mb, true);
  193.         if (err) {
  194.             re_fprintf(stderr, "unable to decode SDP offer: %s\n",
  195.                    strerror(err));
  196.             goto out;
  197.         }
  198.  
  199.         update_media();
  200.     }
  201.  
  202.     /* Encode SDP */
  203.     err = sdp_encode(&mb, sdp, !got_offer);
  204.     if (err) {
  205.         re_fprintf(stderr, "unable to encode SDP: %s\n",
  206.                strerror(err));
  207.         goto out;
  208.     }
  209.  
  210.     /* Answer incoming call */
  211.     err = sipsess_accept(&sess, sess_sock, msg, 200, "OK",
  212.                  name, "application/sdp", mb,
  213.                  auth_handler, NULL, false,
  214.                  offer_handler, answer_handler,
  215.                  establish_handler, NULL, NULL,
  216.                  close_handler, NULL, NULL);
  217.     mem_deref(mb); /* free SDP buffer */
  218.     if (err) {
  219.         re_fprintf(stderr, "session accept error: %s\n",
  220.                strerror(err));
  221.         goto out;
  222.     }
  223.  
  224.  out:
  225.     if (err) {
  226.         (void)sip_treply(NULL, sip, msg, 500, strerror(err));
  227.     }
  228.     else {
  229.         re_printf("accepting incoming call from <%r>\n",
  230.               &msg->from.auri);
  231.     }
  232. }
  233.  
  234.  
  235. /* called when register responses are received */
  236. static void register_handler(int err, const struct sip_msg *msg, void *arg)
  237. {
  238.     (void)arg;
  239.  
  240.     if (err)
  241.         re_printf("register error: %s\n", strerror(err));
  242.     else
  243.         re_printf("register reply: %u %r\n", msg->scode, &msg->reason);
  244. }
  245.  
  246.  
  247. /* called when all sip transactions are completed */
  248. static void exit_handler(void *arg)
  249. {
  250.     (void)arg;
  251.  
  252.     /* stop libre main loop */
  253.     re_cancel();
  254. }
  255.  
  256.  
  257. /* called upon reception of  SIGINT, SIGALRM or SIGTERM */
  258. static void signal_handler(int sig)
  259. {
  260.     re_printf("terminating on signal %d...\n", sig);
  261.  
  262.     terminate();
  263. }
  264.  
  265.  
  266. int main(int argc, char *argv[])
  267. {
  268.     struct sa nsv[16];
  269.     struct dnsc *dnsc = NULL;
  270.     struct sa laddr;
  271.     uint32_t nsc;
  272.     int err; /* errno return values */
  273.  
  274.     /* enable coredumps to aid debugging */
  275.     (void)sys_coredump_set(true);
  276.  
  277.     /* initialize libre state */
  278.     err = libre_init();
  279.     if (err) {
  280.         re_fprintf(stderr, "re init failed: %s\n", strerror(err));
  281.         goto out;
  282.     }
  283.  
  284.     nsc = ARRAY_SIZE(nsv);
  285.  
  286.     /* fetch list of DNS server IP addresses */
  287.     err = dns_srv_get(NULL, 0, nsv, &nsc);
  288.     if (err) {
  289.         re_fprintf(stderr, "unable to get dns servers: %s\n",
  290.                strerror(err));
  291.         goto out;
  292.     }
  293.  
  294.     /* create DNS client */
  295.     err = dnsc_alloc(&dnsc, NULL, nsv, nsc);
  296.     if (err) {
  297.         re_fprintf(stderr, "unable to create dns client: %s\n",
  298.                strerror(err));
  299.         goto out;
  300.     }
  301.  
  302.     /* create SIP stack instance */
  303.     err = sip_alloc(&sip, dnsc, 32, 32, 32,
  304.             "ua demo v" VERSION " (" ARCH "/" OS ")",
  305.             exit_handler, NULL);
  306.     if (err) {
  307.         re_fprintf(stderr, "sip error: %s\n", strerror(err));
  308.         goto out;
  309.     }
  310.  
  311.     /* fetch local IP address */
  312.     err = net_default_source_addr_get(AF_INET, &laddr);
  313.     if (err) {
  314.         re_fprintf(stderr, "local address error: %s\n", strerror(err));
  315.         goto out;
  316.     }
  317.  
  318.     /* listen on random port */
  319.     sa_set_port(&laddr, 0);
  320.  
  321.     /* add supported SIP transports */
  322.     err |= sip_transp_add(sip, SIP_TRANSP_UDP, &laddr);
  323.     err |= sip_transp_add(sip, SIP_TRANSP_TCP, &laddr);
  324.     if (err) {
  325.         re_fprintf(stderr, "transport error: %s\n", strerror(err));
  326.         goto out;
  327.     }
  328.  
  329.     /* create SIP session socket */
  330.     err = sipsess_listen(&sess_sock, sip, 32, connect_handler, NULL);
  331.     if (err) {
  332.         re_fprintf(stderr, "session listen error: %s\n",
  333.                strerror(err));
  334.         goto out;
  335.     }
  336.  
  337.     /* create SDP session */
  338.     err = sdp_session_alloc(&sdp, &laddr);
  339.     if (err) {
  340.         re_fprintf(stderr, "sdp session error: %s\n", strerror(err));
  341.         goto out;
  342.     }
  343.  
  344.     /* add audio sdp media, using dummy port: 4242 */
  345.     err = sdp_media_add(&sdp_media, sdp, "audio", 4242, "RTP/AVP");
  346.     if (err) {
  347.         re_fprintf(stderr, "sdp media error: %s\n", strerror(err));
  348.         goto out;
  349.     }
  350.  
  351.     /* add G.711 sdp media format */
  352.     err = sdp_format_add(NULL, sdp_media, false, "0", "PCMU", 8000, 1,
  353.                  NULL, NULL, NULL, false, NULL);
  354.     if (err) {
  355.         re_fprintf(stderr, "sdp format error: %s\n", strerror(err));
  356.         goto out;
  357.     }
  358.  
  359.     /* invite provided URI */
  360.     if (argc > 1) {
  361.  
  362.         struct mbuf *mb;
  363.  
  364.         /* create SDP offer */
  365.         err = sdp_encode(&mb, sdp, true);
  366.         if (err) {
  367.             re_fprintf(stderr, "sdp encode error: %s\n",
  368.                    strerror(err));
  369.             goto out;
  370.         }
  371.  
  372.         err = sipsess_connect(&sess, sess_sock, argv[1], name,
  373.                       uri, name,
  374.                       NULL, 0, "application/sdp", mb,
  375.                       auth_handler, NULL, false,
  376.                       offer_handler, answer_handler,
  377.                       progress_handler, establish_handler,
  378.                       NULL, NULL, close_handler, NULL, NULL);
  379.         mem_deref(mb); /* free SDP buffer */
  380.         if (err) {
  381.             re_fprintf(stderr, "session connect error: %s\n",
  382.                    strerror(err));
  383.             goto out;
  384.         }
  385.  
  386.         re_printf("inviting <%s>...\n", argv[1]);
  387.     }
  388.     else {
  389.  
  390.         err = sipreg_register(&reg, sip, registrar, uri, uri, 60, name,
  391.                       NULL, 0, 0, auth_handler, NULL, false,
  392.                       register_handler, NULL, NULL, NULL);
  393.         if (err) {
  394.             re_fprintf(stderr, "register error: %s\n",
  395.                    strerror(err));
  396.             goto out;
  397.         }
  398.  
  399.         re_printf("registering <%s>...\n", uri);
  400.     }
  401.  
  402.     /* main loop */
  403.     err = re_main(signal_handler);
  404.  
  405.  out:
  406.     /* clean up/free all state */
  407.     mem_deref(sdp); /* will alse free sdp_media */
  408.     mem_deref(sess_sock);
  409.     mem_deref(sip);
  410.     mem_deref(dnsc);
  411.  
  412.     /* free librar state */
  413.     libre_close();
  414.  
  415.     /* check for memory leaks */
  416.     tmr_debug();
  417.     mem_debug();
  418.  
  419.     return err;
  420. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement