/** * Listen to incoming SIP MESSAGE messages * * @param message Messaging subsystem * @param recvh Message receive handler * @param arg Handler argument * * @return 0 if success, otherwise errorcode */ int message_listen(struct message *message, message_recv_h *recvh, void *arg) { struct message_lsnr *lsnr; int err = 0; if (!message || !recvh) return EINVAL; /* create the SIP listener if it does not exist */ if (!message->sip_lsnr) { err = sip_listen(&message->sip_lsnr, uag_sip(), true, request_handler, message); if (err) goto out; } lsnr = mem_zalloc(sizeof(*lsnr), listener_destructor); if (!lsnr) return ENOMEM; lsnr->recvh = recvh; lsnr->arg = arg; list_append(&message->lsnrl, &lsnr->le, lsnr); out: return err; }
int sip_ctrans_init(struct sip *sip, uint32_t sz) { int err; err = sip_listen(NULL, sip, false, response_handler, sip); if (err) return err; return hash_alloc(&sip->ht_ctrans, sz); }
/** * Listen to a SIP Session socket for incoming connections * * @param sockp Pointer to allocated SIP Session socket * @param sip SIP Stack instance * @param htsize Hashtable size * @param connh Connection handler * @param arg Handler argument * * @return 0 if success, otherwise errorcode */ int sipsess_listen(struct sipsess_sock **sockp, struct sip *sip, int htsize, sipsess_conn_h *connh, void *arg) { struct sipsess_sock *sock; int err; DEBUG_WARNING("re.sipsess.listen.sipsess_listen()\n"); if (!sockp || !sip || !htsize) return EINVAL; sock = mem_zalloc(sizeof(*sock), destructor); if (!sock) return ENOMEM; err = sip_listen(&sock->lsnr_resp, sip, false, response_handler, sock); if (err) goto out; err = sip_listen(&sock->lsnr_req, sip, true, request_handler, sock); if (err) goto out; err = hash_alloc(&sock->ht_sess, htsize); if (err) goto out; err = hash_alloc(&sock->ht_ack, htsize); if (err) goto out; sock->sip = sip; sock->connh = connh ? connh : internal_connect_handler; sock->arg = connh ? arg : sock; out: if (err) mem_deref(sock); else *sockp = sock; return err; }
int message_init(message_recv_h *h, void *arg) { int err; err = sip_listen(&lsnr, uag_sip(), true, request_handler, NULL); if (err) return err; recvh = h; recvarg = arg; return 0; }
/** * Initialise the User-Agents * * @param software SIP User-Agent string * @param udp Enable UDP transport * @param tcp Enable TCP transport * @param tls Enable TLS transport * @param prefer_ipv6 Prefer IPv6 flag * * @return 0 if success, otherwise errorcode */ int ua_init(const char *software, bool udp, bool tcp, bool tls, bool prefer_ipv6) { struct config *cfg = conf_config(); uint32_t bsize; int err; uag.cfg = &cfg->sip; bsize = cfg->sip.trans_bsize; play_init(); err = contact_init(); if (err) return err; /* Initialise Network */ err = net_init(&cfg->net, prefer_ipv6 ? AF_INET6 : AF_INET); if (err) { warning("ua: network init failed: %m\n", err); return err; } uag.use_udp = udp; uag.use_tcp = tcp; uag.use_tls = tls; uag.prefer_ipv6 = prefer_ipv6; list_init(&uag.ual); err = sip_alloc(&uag.sip, net_dnsc(), bsize, bsize, bsize, software, exit_handler, NULL); if (err) { warning("ua: sip stack failed: %m\n", err); goto out; } err = ua_add_transp(); if (err) goto out; err = sip_listen(&uag.lsnr, uag.sip, true, request_handler, NULL); if (err) goto out; err = sipsess_listen(&uag.sock, uag.sip, bsize, sipsess_conn_handler, NULL); if (err) goto out; err = sipevent_listen(&uag.evsock, uag.sip, bsize, bsize, NULL, NULL); if (err) goto out; err = cmd_register(cmdv, ARRAY_SIZE(cmdv)); if (err) goto out; net_change(60, net_change_handler, NULL); out: if (err) { warning("ua: init failed (%m)\n", err); ua_close(); } return err; }