static void pairing_rnd(struct smp_conn *conn, const void *data, uint16_t len)
{
	struct bthost *bthost = conn->smp->bthost;
	uint8_t rsp[17];

	memcpy(conn->rrnd, data + 1, 16);

	if (!verify_random(conn, data + 1))
		return;

	if (conn->out)
		return;

	rsp[0] = BT_L2CAP_SMP_PAIRING_RANDOM;
	memset(&rsp[1], 0, 16);

	bthost_send_cid(bthost, conn->handle, SMP_CID, rsp, sizeof(rsp));
}
Exemplo n.º 2
0
static void smp_server(const void *data, uint16_t len, void *user_data)
{
	struct test_data *test_data = user_data;
	struct bthost *bthost = hciemu_client_get_host(test_data->hciemu);
	const struct smp_data *smp = test_data->test_data;
	const struct smp_req_rsp *req;
	const void *pdu;
	uint8_t opcode;

	if (len < 1) {
		tester_warn("Received too small SMP PDU");
		goto failed;
	}

	opcode = *((const uint8_t *) data);

	tester_print("Received SMP opcode 0x%02x", opcode);

	if (test_data->counter >= smp->req_count) {
		test_condition_complete(test_data);
		return;
	}

	req = &smp->req[test_data->counter++];
	if (!req->expect)
		goto next;

	if (req->expect_len != len) {
		tester_warn("Unexpected SMP PDU length (%u != %u)",
							len, req->expect_len);
		goto failed;
	}

	switch (opcode) {
	case 0x01: /* Pairing Request */
		memcpy(test_data->preq, data, sizeof(test_data->preq));
		break;
	case 0x02: /* Pairing Response */
		memcpy(test_data->prsp, data, sizeof(test_data->prsp));
		break;
	case 0x03: /* Pairing Confirm */
		memcpy(test_data->pcnf, data + 1, 16);
		goto next;
	case 0x04: /* Pairing Random */
		memcpy(test_data->rrnd, data + 1, 16);
		if (!verify_random(data + 1))
			goto failed;
		goto next;
	default:
		break;
	}

	if (memcmp(req->expect, data, len) != 0) {
		tester_warn("Unexpected SMP PDU");
		goto failed;
	}

next:
	if (smp->req_count == test_data->counter) {
		test_condition_complete(test_data);
		return;
	}

	req = &smp->req[test_data->counter];

	pdu = get_pdu(req->send);
	bthost_send_cid(bthost, test_data->handle, SMP_CID, pdu,
							req->send_len);

	if (!req->expect)
		test_condition_complete(test_data);

	return;

failed:
	tester_test_failed();
}