1 /**
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
18 enum {
19 BFCP_T2 = 10000,
20 };
21
22
tmr_handler(void * arg)23 static 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 */
bfcp_reply(struct bfcp_conn * bc,const struct bfcp_msg * req,enum bfcp_prim prim,unsigned attrc,...)41 int 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 */
bfcp_edreply(struct bfcp_conn * bc,const struct bfcp_msg * req,enum bfcp_err code,const uint8_t * details,size_t len)97 int 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 */
bfcp_ereply(struct bfcp_conn * bc,const struct bfcp_msg * req,enum bfcp_err code)120 int 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 }
125