blob: 321429c42f85a1507cbfb31fdf0c6526c9c431e8 [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
2 * @file bfcp/reply.c BFCP Reply
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6#include <string.h>
7#include <re_types.h>
8#include <re_fmt.h>
9#include <re_mem.h>
10#include <re_mbuf.h>
11#include <re_list.h>
12#include <re_sa.h>
13#include <re_tmr.h>
14#include <re_bfcp.h>
15#include "bfcp.h"
16
17
18enum {
19 BFCP_T2 = 10000,
20};
21
22
23static void tmr_handler(void *arg)
24{
25 struct bfcp_conn *bc = arg;
26
27 bc->mb = mem_deref(bc->mb);
28}
29
30
31/**
32 * Send a BFCP response
33 *
34 * @param bc BFCP connection
35 * @param req BFCP request message
36 * @param prim BFCP Primitive
37 * @param attrc Number of attributes
38 *
39 * @return 0 if success, otherwise errorcode
40 */
41int bfcp_reply(struct bfcp_conn *bc, const struct bfcp_msg *req,
42 enum bfcp_prim prim, unsigned attrc, ...)
43{
44 va_list ap;
45 int err;
46
47 if (!bc || !req)
48 return EINVAL;
49
50 bc->mb = mem_deref(bc->mb);
51 tmr_cancel(&bc->tmr2);
52
53 bc->mb = mbuf_alloc(64);
54 if (!bc->mb)
55 return ENOMEM;
56
57 va_start(ap, attrc);
58 err = bfcp_msg_vencode(bc->mb, req->ver, true, prim, req->confid,
59 req->tid, req->userid, attrc, &ap);
60 va_end(ap);
61
62 if (err)
63 goto out;
64
65 bc->mb->pos = 0;
66
67 err = bfcp_send(bc, &req->src, bc->mb);
68 if (err)
69 goto out;
70
71 bc->st.prim = req->prim;
72 bc->st.confid = req->confid;
73 bc->st.tid = req->tid;
74 bc->st.userid = req->userid;
75
76 tmr_start(&bc->tmr2, BFCP_T2, tmr_handler, bc);
77
78 out:
79 if (err)
80 bc->mb = mem_deref(bc->mb);
81
82 return err;
83}
84
85
86/**
87 * Send a BFCP error response with details
88 *
89 * @param bc BFCP connection
90 * @param req BFCP request message
91 * @param code Error code
92 * @param details Error details
93 * @param len Details length
94 *
95 * @return 0 if success, otherwise errorcode
96 */
97int bfcp_edreply(struct bfcp_conn *bc, const struct bfcp_msg *req,
98 enum bfcp_err code, const uint8_t *details, size_t len)
99{
100 struct bfcp_errcode errcode;
101
102 errcode.code = code;
103 errcode.details = (uint8_t *)details;
104 errcode.len = len;
105
106 return bfcp_reply(bc, req, BFCP_ERROR, 1,
107 BFCP_ERROR_CODE, 0, &errcode);
108}
109
110
111/**
112 * Send a BFCP error response
113 *
114 * @param bc BFCP connection
115 * @param req BFCP request message
116 * @param code Error code
117 *
118 * @return 0 if success, otherwise errorcode
119 */
120int bfcp_ereply(struct bfcp_conn *bc, const struct bfcp_msg *req,
121 enum bfcp_err code)
122{
123 return bfcp_edreply(bc, req, code, NULL, 0);
124}