Home | History | Annotate | Download | only in hw

Lines Matching refs:l2cap

2  * QEMU Bluetooth L2CAP logic.
53 struct l2cap_instance_s *l2cap;
94 struct l2cap_instance_s l2cap;
163 /* L2CAP layer logic (protocol) */
185 static void l2cap_command_reject(struct l2cap_instance_s *l2cap, int id,
196 pkt = l2cap->signalling_ch.params.sdu_out(&l2cap->signalling_ch.params,
208 l2cap->signalling_ch.params.sdu_submit(&l2cap->signalling_ch.params);
211 static void l2cap_command_reject_cid(struct l2cap_instance_s *l2cap, int id,
219 l2cap_command_reject(l2cap, id, reason, &params, L2CAP_CMD_REJ_CID_SIZE);
222 static void l2cap_connection_response(struct l2cap_instance_s *l2cap,
229 pkt = l2cap->signalling_ch.params.sdu_out(&l2cap->signalling_ch.params,
235 hdr->ident = l2cap->last_id;
243 l2cap->signalling_ch.params.sdu_submit(&l2cap->signalling_ch.params);
246 static void l2cap_configuration_request(struct l2cap_instance_s *l2cap,
253 pkt = l2cap->signalling_ch.params.sdu_out(&l2cap->signalling_ch.params,
259 l2cap->last_id = l2cap->next_id;
260 l2cap->next_id = l2cap->next_id == 255 ? 1 : l2cap->next_id + 1;
263 hdr->ident = l2cap->last_id;
271 l2cap->signalling_ch.params.sdu_submit(&l2cap->signalling_ch.params);
274 static void l2cap_configuration_response(struct l2cap_instance_s *l2cap,
281 pkt = l2cap->signalling_ch.params.sdu_out(&l2cap->signalling_ch.params,
287 hdr->ident = l2cap->last_id;
296 l2cap->signalling_ch.params.sdu_submit(&l2cap->signalling_ch.params);
299 static void l2cap_disconnection_response(struct l2cap_instance_s *l2cap,
306 pkt = l2cap->signalling_ch.params.sdu_out(&l2cap->signalling_ch.params,
312 hdr->ident = l2cap->last_id;
318 l2cap->signalling_ch.params.sdu_submit(&l2cap->signalling_ch.params);
321 static void l2cap_echo_response(struct l2cap_instance_s *l2cap,
328 pkt = l2cap->signalling_ch.params.sdu_out(&l2cap->signalling_ch.params,
334 hdr->ident = l2cap->last_id;
339 l2cap->signalling_ch.params.sdu_submit(&l2cap->signalling_ch.params);
342 static void l2cap_info_response(struct l2cap_instance_s *l2cap, int type,
349 pkt = l2cap->signalling_ch.params.sdu_out(&l2cap->signalling_ch.params,
355 hdr->ident = l2cap->last_id;
363 l2cap->signalling_ch.params.sdu_submit(&l2cap->signalling_ch.params);
377 static int l2cap_cid_new(struct l2cap_instance_s *l2cap)
382 if (!l2cap->cid[i])
399 static struct l2cap_chan_s *l2cap_channel_open(struct l2cap_instance_s *l2cap,
405 int cid = l2cap_cid_new(l2cap);
409 psm_info = l2cap_psm(l2cap->dev, psm);
422 ch->l2cap = l2cap;
425 if (!psm_info->new_channel(l2cap->dev, &ch->params)) {
426 l2cap->cid[cid] = ch;
445 l2cap_connection_response(l2cap, cid, source_cid, result, status);
450 static void l2cap_channel_close(struct l2cap_instance_s *l2cap,
459 l2cap_command_reject_cid(l2cap, l2cap->last_id, L2CAP_REJ_CID_INVAL,
464 ch = l2cap->cid[cid];
473 l2cap->cid[cid] = NULL;
479 l2cap_disconnection_response(l2cap, cid, source_cid);
482 static void l2cap_channel_config_null(struct l2cap_instance_s *l2cap,
485 l2cap_configuration_request(l2cap, ch->remote_cid, 0, NULL, 0);
486 ch->config_req_id = l2cap->last_id;
490 static void l2cap_channel_config_req_event(struct l2cap_instance_s *l2cap,
494 l2cap_channel_config_null(l2cap, ch);
497 static int l2cap_channel_config(struct l2cap_instance_s *l2cap,
677 l2cap_configuration_response(l2cap, ch->remote_cid,
683 static void l2cap_channel_config_req_msg(struct l2cap_instance_s *l2cap,
688 if (unlikely(cid >= L2CAP_CID_MAX || !l2cap->cid[cid])) {
689 l2cap_command_reject_cid(l2cap, l2cap->last_id, L2CAP_REJ_CID_INVAL,
693 ch = l2cap->cid[cid];
702 if (l2cap_channel_config(l2cap, ch, flag, data, len))
712 l2cap_channel_config_req_event(l2cap, ch);
715 static int l2cap_channel_config_rsp_msg(struct l2cap_instance_s *l2cap,
720 if (unlikely(cid >= L2CAP_CID_MAX || !l2cap->cid[cid])) {
721 l2cap_command_reject_cid(l2cap, l2cap->last_id, L2CAP_REJ_CID_INVAL,
725 ch = l2cap->cid[cid];
727 if (ch->config_req_id != l2cap->last_id)
735 l2cap_channel_config_null(l2cap, ch);
738 l2cap_channel_config_req_event(l2cap, ch);
743 static void l2cap_channel_open_req_msg(struct l2cap_instance_s *l2cap,
746 struct l2cap_chan_s *ch = l2cap_channel_open(l2cap, psm, source_cid);
753 l2cap_channel_config_req_event(l2cap, ch);
756 static void l2cap_info(struct l2cap_instance_s *l2cap, int type)
764 data[len ++] = l2cap->group_ch.mps & 0xff;
765 data[len ++] = l2cap->group_ch.mps >> 8;
780 l2cap_info_response(l2cap, type, result, data, len);
783 static void l2cap_command(struct l2cap_instance_s *l2cap, int code, int id,
790 if (!id || (id != l2cap->last_id && id != l2cap->next_id)) {
796 l2cap->next_id = id;
798 if (id == l2cap->next_id) {
799 l2cap->last_id = l2cap->next_id;
800 l2cap->next_id = l2cap->next_id == 255 ? 1 : l2cap->next_id + 1;
825 l2cap_channel_open_req_msg(l2cap,
847 l2cap_channel_config_req_msg(l2cap,
860 if (l2cap_channel_config_rsp_msg(l2cap,
876 l2cap_channel_close(l2cap,
893 l2cap_echo_response(l2cap, params, len);
908 l2cap_info(l2cap, le16_to_cpu(((l2cap_info_req *) params)->type));
925 l2cap_command_reject(l2cap, id, err, 0, 0);
941 struct l2cap_instance_s *l2cap = opaque;
955 l2cap_command_reject(l2cap, hdr->ident,
960 l2cap_command(l2cap, hdr->code, hdr->ident, data, clen);
976 /* Basic L2CAP mode Information frame */
1057 static void l2cap_frame_in(struct l2cap_instance_s *l2cap,
1063 if (unlikely(cid >= L2CAP_CID_MAX || !l2cap->cid[cid])) {
1064 fprintf(stderr, "%s: frame addressed to a non-existent L2CAP "
1069 l2cap->cid[cid]->frame_in(l2cap->cid[cid], cid, frame, len);
1073 static void l2cap_pdu_in(struct l2cap_instance_s *l2cap,
1076 const l2cap_hdr *hdr = (void *) l2cap->frame_in;
1078 if (unlikely(len + l2cap->frame_in_len > sizeof(l2cap->frame_in))) {
1079 if (l2cap->frame_in_len < sizeof(l2cap->frame_in)) {
1080 memcpy(l2cap->frame_in + l2cap->frame_in_len, data,
1081 sizeof(l2cap->frame_in) - l2cap->frame_in_len);
1082 l2cap->frame_in_len = sizeof(l2cap->frame_in);
1084 l2cap_frame_in(l2cap, hdr);
1090 memcpy(l2cap->frame_in + l2cap->frame_in_len, data, len);
1091 l2cap->frame_in_len += len;
1095 l2cap_frame_in(l2cap, hdr);
1100 static inline uint8_t *l2cap_pdu_out(struct l2cap_instance_s *l2cap,
1103 l2cap_hdr *hdr = (void *) l2cap->frame_out;
1105 l2cap->frame_out_len = len + L2CAP_HDR_SIZE;
1110 return l2cap->frame_out + L2CAP_HDR_SIZE;
1113 static inline void l2cap_pdu_submit(struct l2cap_instance_s *l2cap)
1116 (l2cap->role ?
1117 l2cap->link->slave->lmp_acl_data : l2cap->link->host->lmp_acl_resp)
1118 (l2cap->link, l2cap->frame_out, 1, l2cap->frame_out_len);
1132 return l2cap_pdu_out(chan->l2cap, chan->remote_cid, len);
1139 return l2cap_pdu_submit(chan->l2cap);
1170 static void l2cap_init(struct l2cap_instance_s *l2cap,
1173 l2cap->link = link;
1174 l2cap->role = role;
1175 l2cap->dev = (struct bt_l2cap_device_s *)
1178 l2cap->next_id = 1;
1181 l2cap->signalling_ch.params.sdu_in = l2cap_cframe_in;
1182 l2cap->signalling_ch.params.sdu_out = l2cap_bframe_out;
1183 l2cap->signalling_ch.params.sdu_submit = l2cap_bframe_submit;
1184 l2cap->signalling_ch.params.opaque = l2cap;
1185 l2cap->signalling_ch.params.remote_mtu = 48;
1186 l2cap->signalling_ch.remote_cid = L2CAP_CID_SIGNALLING;
1187 l2cap->signalling_ch.frame_in = l2cap_bframe_in;
1188 l2cap->signalling_ch.mps = 65536;
1189 l2cap->signalling_ch.min_mtu = 48;
1190 l2cap->signalling_ch.mode = L2CAP_MODE_BASIC;
1191 l2cap->signalling_ch.l2cap = l2cap;
1192 l2cap->cid[L2CAP_CID_SIGNALLING] = &l2cap->signalling_ch;
1195 l2cap->group_ch.params.sdu_in = l2cap_gframe_in;
1196 l2cap->group_ch.params.opaque = l2cap;
1197 l2cap->group_ch.frame_in = l2cap_bframe_in;
1198 l2cap->group_ch.mps = 65533;
1199 l2cap->group_ch.l2cap = l2cap;
1200 l2cap->group_ch.remote_cid = L2CAP_CID_INVALID;
1201 l2cap->cid[L2CAP_CID_GROUP] = &l2cap->group_ch;
1204 static void l2cap_teardown(struct l2cap_instance_s *l2cap, int send_disconnect)
1211 if (l2cap->role)
1212 l2cap->dev->device.lmp_disconnect_slave(l2cap->link);
1213 /* l2cap->link is invalid from now on. */
1215 l2cap->dev->device.lmp_disconnect_master(l2cap->link);
1219 if (l2cap->cid[cid]) {
1220 l2cap->cid[cid]->params.close(l2cap->cid[cid]->params.opaque);
1221 qemu_free(l2cap->cid[cid]);
1224 if (l2cap->role)
1225 qemu_free(l2cap);
1227 qemu_free(l2cap->link);
1230 /* L2CAP glue to lower layers in bluetooth stack (LMP) */
1235 struct slave_l2cap_instance_s *l2cap;
1239 l2cap = qemu_mallocz(sizeof(struct slave_l2cap_instance_s));
1240 l2cap->link.slave = &dev->device;
1241 l2cap->link.host = link->host;
1242 l2cap_init(&l2cap->l2cap, &l2cap->link, 0);
1246 link->host->lmp_connection_complete(&l2cap->link);
1253 struct l2cap_instance_s *l2cap;
1260 l2cap = qemu_mallocz(sizeof(struct l2cap_instance_s));
1261 l2cap_init(l2cap, link, 1);
1272 struct l2cap_instance_s *l2cap =
1277 l2cap_teardown(l2cap, 0);
1282 struct slave_l2cap_instance_s *l2cap =
1285 l2cap_teardown(&l2cap->l2cap, 0);
1291 struct slave_l2cap_instance_s *l2cap =
1295 l2cap->l2cap.frame_in_len = 0;
1297 l2cap_pdu_in(&l2cap->l2cap, data, len);
1305 struct l2cap_instance_s *l2cap =
1309 l2cap->frame_in_len = 0;
1311 l2cap_pdu_in(l2cap, data, len);