aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap_core.c
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2011-10-17 07:35:30 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-10-17 16:09:06 -0400
commit42dceae2819b5ac6fc9a0d414ae05a8960e2a1d9 (patch)
tree1ca8c1faf83db4152aa0b257a8381a8e07ea4bd8 /net/bluetooth/l2cap_core.c
parentc8f791626a8840fe60a05ab55468dfb3922cb35a (diff)
Bluetooth: EFS: parse L2CAP config request
Add parsing Extended Flow Specification option in L2CAP Config Request Based upon haijun.liu <haijun.liu@atheros.com> series of patches (sent Sun, 22 Aug 2010) Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/l2cap_core.c')
-rw-r--r--net/bluetooth/l2cap_core.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 78911269d901..bda6da797734 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2115,6 +2115,8 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
2115 int type, hint, olen; 2115 int type, hint, olen;
2116 unsigned long val; 2116 unsigned long val;
2117 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; 2117 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
2118 struct l2cap_conf_efs efs;
2119 u8 remote_efs = 0;
2118 u16 mtu = L2CAP_DEFAULT_MTU; 2120 u16 mtu = L2CAP_DEFAULT_MTU;
2119 u16 result = L2CAP_CONF_SUCCESS; 2121 u16 result = L2CAP_CONF_SUCCESS;
2120 u16 size; 2122 u16 size;
@@ -2147,7 +2149,12 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
2147 case L2CAP_CONF_FCS: 2149 case L2CAP_CONF_FCS:
2148 if (val == L2CAP_FCS_NONE) 2150 if (val == L2CAP_FCS_NONE)
2149 set_bit(CONF_NO_FCS_RECV, &chan->conf_state); 2151 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
2152 break;
2150 2153
2154 case L2CAP_CONF_EFS:
2155 remote_efs = 1;
2156 if (olen == sizeof(efs))
2157 memcpy(&efs, (void *) val, olen);
2151 break; 2158 break;
2152 2159
2153 case L2CAP_CONF_EWS: 2160 case L2CAP_CONF_EWS:
@@ -2182,6 +2189,13 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
2182 break; 2189 break;
2183 } 2190 }
2184 2191
2192 if (remote_efs) {
2193 if (__l2cap_efs_supported(chan))
2194 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2195 else
2196 return -ECONNREFUSED;
2197 }
2198
2185 if (chan->mode != rfc.mode) 2199 if (chan->mode != rfc.mode)
2186 return -ECONNREFUSED; 2200 return -ECONNREFUSED;
2187 2201
@@ -2200,7 +2214,6 @@ done:
2200 sizeof(rfc), (unsigned long) &rfc); 2214 sizeof(rfc), (unsigned long) &rfc);
2201 } 2215 }
2202 2216
2203
2204 if (result == L2CAP_CONF_SUCCESS) { 2217 if (result == L2CAP_CONF_SUCCESS) {
2205 /* Configure output options and let the other side know 2218 /* Configure output options and let the other side know
2206 * which ones we don't like. */ 2219 * which ones we don't like. */
@@ -2213,6 +2226,22 @@ done:
2213 } 2226 }
2214 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); 2227 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
2215 2228
2229 if (remote_efs) {
2230 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
2231 efs.stype != L2CAP_SERV_NOTRAFIC &&
2232 efs.stype != chan->local_stype) {
2233
2234 result = L2CAP_CONF_UNACCEPT;
2235
2236 if (chan->num_conf_req >= 1)
2237 return -ECONNREFUSED;
2238
2239 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
2240 sizeof(efs),
2241 (unsigned long) &efs);
2242 }
2243 }
2244
2216 switch (rfc.mode) { 2245 switch (rfc.mode) {
2217 case L2CAP_MODE_BASIC: 2246 case L2CAP_MODE_BASIC:
2218 chan->fcs = L2CAP_FCS_NONE; 2247 chan->fcs = L2CAP_FCS_NONE;
@@ -2245,6 +2274,19 @@ done:
2245 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, 2274 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
2246 sizeof(rfc), (unsigned long) &rfc); 2275 sizeof(rfc), (unsigned long) &rfc);
2247 2276
2277 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
2278 chan->remote_id = efs.id;
2279 chan->remote_stype = efs.stype;
2280 chan->remote_msdu = le16_to_cpu(efs.msdu);
2281 chan->remote_flush_to =
2282 le32_to_cpu(efs.flush_to);
2283 chan->remote_acc_lat =
2284 le32_to_cpu(efs.acc_lat);
2285 chan->remote_sdu_itime =
2286 le32_to_cpu(efs.sdu_itime);
2287 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
2288 sizeof(efs), (unsigned long) &efs);
2289 }
2248 break; 2290 break;
2249 2291
2250 case L2CAP_MODE_STREAMING: 2292 case L2CAP_MODE_STREAMING: