hsp_hs.c (0e2df43f5cbae3fc71139523458b98f30307d21b) hsp_hs.c (a0ffb263e02c613f9155d5035f68cb0ad7b80d74)
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 147 unchanged lines hidden (view full) ---

156
157// remote audio volume control
158// AG +VGM=13 [0..15] ; HS AT+VGM=6 | AG OK
159
160static int hsp_hs_send_str_over_rfcomm(uint16_t cid, const char * command){
161 if (!rfcomm_can_send_packet_now(rfcomm_cid)) return 1;
162 int err = rfcomm_send(cid, (uint8_t*) command, strlen(command));
163 if (err){
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 147 unchanged lines hidden (view full) ---

156
157// remote audio volume control
158// AG +VGM=13 [0..15] ; HS AT+VGM=6 | AG OK
159
160static int hsp_hs_send_str_over_rfcomm(uint16_t cid, const char * command){
161 if (!rfcomm_can_send_packet_now(rfcomm_cid)) return 1;
162 int err = rfcomm_send(cid, (uint8_t*) command, strlen(command));
163 if (err){
164 printf("rfcomm_send -> error 0X%02x", err);
164 log_info("rfcomm_send_internal -> error 0X%02x", err);
165 }
166 return err;
167}
168
169void hsp_hs_enable_custom_indications(int enable){
170 hs_support_custom_indications = enable;
171}
172

--- 110 unchanged lines hidden (view full) ---

283 hsp_state = HSP_SDP_QUERY_RFCOMM_CHANNEL;
284 memcpy(remote, bd_addr, 6);
285 hsp_run();
286}
287
288void hsp_hs_disconnect(bd_addr_t bd_addr){
289 switch (hsp_state){
290 case HSP_ACTIVE:
165 }
166 return err;
167}
168
169void hsp_hs_enable_custom_indications(int enable){
170 hs_support_custom_indications = enable;
171}
172

--- 110 unchanged lines hidden (view full) ---

283 hsp_state = HSP_SDP_QUERY_RFCOMM_CHANNEL;
284 memcpy(remote, bd_addr, 6);
285 hsp_run();
286}
287
288void hsp_hs_disconnect(bd_addr_t bd_addr){
289 switch (hsp_state){
290 case HSP_ACTIVE:
291 printf("HSP_W4_USER_ACTION\n");
292 hsp_state = HSP_W4_USER_ACTION;
293 hs_send_button_press = 1;
294 break;
295 case HSP_W4_RFCOMM_CONNECTED:
291 hsp_state = HSP_W4_USER_ACTION;
292 hs_send_button_press = 1;
293 break;
294 case HSP_W4_RFCOMM_CONNECTED:
296 printf("HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN \n");
297 hsp_state = HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
298 break;
299 default:
300 return;
301 }
302 hsp_run();
303}
304
305
306void hsp_hs_set_microphone_gain(uint8_t gain){
307 if (gain < 0 || gain >15) {
295 hsp_state = HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
296 break;
297 default:
298 return;
299 }
300 hsp_run();
301}
302
303
304void hsp_hs_set_microphone_gain(uint8_t gain){
305 if (gain < 0 || gain >15) {
308 printf("Gain must be in interval [0..15], it is given %d\n", gain);
306 log_info("Gain must be in interval [0..15], it is given %d", gain);
309 return;
310 }
311 hs_microphone_gain = gain;
312 hsp_run();
313}
314
315// AG +VGS=5 [0..15] ; HS AT+VGM=6 | AG OK
316void hsp_hs_set_speaker_gain(uint8_t gain){
317 if (gain < 0 || gain >15) {
307 return;
308 }
309 hs_microphone_gain = gain;
310 hsp_run();
311}
312
313// AG +VGS=5 [0..15] ; HS AT+VGM=6 | AG OK
314void hsp_hs_set_speaker_gain(uint8_t gain){
315 if (gain < 0 || gain >15) {
318 printf("Gain must be in interval [0..15], it is given %d\n", gain);
316 log_info("Gain must be in interval [0..15], it is given %d", gain);
319 return;
320 }
321 hs_speaker_gain = gain;
322 hsp_run();
323}
324
325
326static void hsp_run(void){

--- 61 unchanged lines hidden (view full) ---

388 // skip over leading newline
389 while (size > 0 && (packet[0] == '\n' || packet[0] == '\r')){
390 size--;
391 packet++;
392 }
393 if (strncmp((char *)packet, HSP_AG_RING, strlen(HSP_AG_RING)) == 0){
394 emit_ring_event();
395 } else if (strncmp((char *)packet, HSP_AG_OK, strlen(HSP_AG_OK)) == 0){
317 return;
318 }
319 hs_speaker_gain = gain;
320 hsp_run();
321}
322
323
324static void hsp_run(void){

--- 61 unchanged lines hidden (view full) ---

386 // skip over leading newline
387 while (size > 0 && (packet[0] == '\n' || packet[0] == '\r')){
388 size--;
389 packet++;
390 }
391 if (strncmp((char *)packet, HSP_AG_RING, strlen(HSP_AG_RING)) == 0){
392 emit_ring_event();
393 } else if (strncmp((char *)packet, HSP_AG_OK, strlen(HSP_AG_OK)) == 0){
396 printf("OK RECEIVED\n");
397 switch (hsp_state){
398 case HSP_W4_RFCOMM_CONNECTED:
399 hsp_state = HSP_W2_CONNECT_SCO;
400 break;
401 case HSP_W4_USER_ACTION:
402 hsp_state = HSP_W2_DISCONNECT_SCO;
403 break;
404 default:

--- 27 unchanged lines hidden (view full) ---

432 }
433
434 if (packet_type != HCI_EVENT_PACKET) return;
435 uint8_t event = hci_event_packet_get_type(packet);
436 bd_addr_t event_addr;
437 uint16_t handle;
438
439 switch (event) {
394 switch (hsp_state){
395 case HSP_W4_RFCOMM_CONNECTED:
396 hsp_state = HSP_W2_CONNECT_SCO;
397 break;
398 case HSP_W4_USER_ACTION:
399 hsp_state = HSP_W2_DISCONNECT_SCO;
400 break;
401 default:

--- 27 unchanged lines hidden (view full) ---

429 }
430
431 if (packet_type != HCI_EVENT_PACKET) return;
432 uint8_t event = hci_event_packet_get_type(packet);
433 bd_addr_t event_addr;
434 uint16_t handle;
435
436 switch (event) {
440 case BTSTACK_EVENT_STATE:
441 // bt stack activated, get started
442 if (packet[2] == HCI_STATE_WORKING){
443 printf("BTstack activated, get started .\n");
444 }
445 hsp_hs_callback(packet, size);
446 break;
447
448 case HCI_EVENT_PIN_CODE_REQUEST:
449 // inform about pin code request
450 printf("Pin code request - using '0000'\n\r");
451 reverse_bd_addr(&packet[2], event_addr);
452 hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
453 break;
454 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
455 int index = 2;
456 uint8_t status = packet[index++];
457 sco_handle = little_endian_read_16(packet, index);
458 index+=2;
459 bd_addr_t address;
460 memcpy(address, &packet[index], 6);
461 index+=6;

--- 8 unchanged lines hidden (view full) ---

470
471 if (status != 0){
472 log_error("(e)SCO Connection failed, status %u", status);
473 emit_event_audio_connected(status, sco_handle);
474 break;
475 }
476 switch (link_type){
477 case 0x00:
437 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
438 int index = 2;
439 uint8_t status = packet[index++];
440 sco_handle = little_endian_read_16(packet, index);
441 index+=2;
442 bd_addr_t address;
443 memcpy(address, &packet[index], 6);
444 index+=6;

--- 8 unchanged lines hidden (view full) ---

453
454 if (status != 0){
455 log_error("(e)SCO Connection failed, status %u", status);
456 emit_event_audio_connected(status, sco_handle);
457 break;
458 }
459 switch (link_type){
460 case 0x00:
478 printf("SCO Connection established. \n");
461 log_info("SCO Connection established.");
479 if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval);
480 if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval);
481 if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length);
482 if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length);
483 break;
484 case 0x02:
462 if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval);
463 if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval);
464 if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length);
465 if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length);
466 break;
467 case 0x02:
485 printf("eSCO Connection established. \n");
468 log_info("eSCO Connection established.");
486 break;
487 default:
488 log_error("(e)SCO reserved link_type 0x%2x", link_type);
489 break;
490 }
491 log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, "
492 " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)", sco_handle,
493 bd_addr_to_str(address), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode);

--- 12 unchanged lines hidden (view full) ---

506 }
507
508 case RFCOMM_EVENT_INCOMING_CONNECTION:
509 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
510 if (hsp_state != HSP_IDLE) return;
511
512 reverse_bd_addr(&packet[2], event_addr);
513 rfcomm_cid = little_endian_read_16(packet, 9);
469 break;
470 default:
471 log_error("(e)SCO reserved link_type 0x%2x", link_type);
472 break;
473 }
474 log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, "
475 " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)", sco_handle,
476 bd_addr_to_str(address), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode);

--- 12 unchanged lines hidden (view full) ---

489 }
490
491 case RFCOMM_EVENT_INCOMING_CONNECTION:
492 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
493 if (hsp_state != HSP_IDLE) return;
494
495 reverse_bd_addr(&packet[2], event_addr);
496 rfcomm_cid = little_endian_read_16(packet, 9);
514 printf("RFCOMM channel %u requested for %s\n", packet[8], bd_addr_to_str(event_addr));
497 log_info("RFCOMM channel %u requested for %s", packet[8], bd_addr_to_str(event_addr));
515 rfcomm_accept_connection(rfcomm_cid);
516
517 hsp_state = HSP_W4_RFCOMM_CONNECTED;
518 break;
519
520 case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
498 rfcomm_accept_connection(rfcomm_cid);
499
500 hsp_state = HSP_W4_RFCOMM_CONNECTED;
501 break;
502
503 case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
521 printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u\n", packet_type);
504 // printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u, packet[0] %x\n", packet_type, packet[0]);
522 // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
523 if (packet[2]) {
505 // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
506 if (packet[2]) {
524 printf("RFCOMM channel open failed, status %u\n", packet[2]);
507 log_info("RFCOMM channel open failed, status %u", packet[2]);
525 hsp_hs_reset_state();
526 emit_event(HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, packet[2]);
527 hs_outgoing_connection = 0;
528 } else {
529 // data: event(8) , len(8), status (8), address (48), handle (16), server channel(8), rfcomm_cid(16), max frame size(16)
530 rfcomm_handle = little_endian_read_16(packet, 9);
531 rfcomm_cid = little_endian_read_16(packet, 12);
532 mtu = little_endian_read_16(packet, 14);
508 hsp_hs_reset_state();
509 emit_event(HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, packet[2]);
510 hs_outgoing_connection = 0;
511 } else {
512 // data: event(8) , len(8), status (8), address (48), handle (16), server channel(8), rfcomm_cid(16), max frame size(16)
513 rfcomm_handle = little_endian_read_16(packet, 9);
514 rfcomm_cid = little_endian_read_16(packet, 12);
515 mtu = little_endian_read_16(packet, 14);
533 printf("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n", rfcomm_cid, mtu);
516 log_info("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u", rfcomm_cid, mtu);
534
535 if (hs_outgoing_connection){
536 hs_outgoing_connection = 0;
537 hs_send_button_press = 1;
538 }
539
540 switch (hsp_state){
541 case HSP_W4_RFCOMM_CONNECTED:

--- 12 unchanged lines hidden (view full) ---

554 hsp_hs_callback(packet, size);
555 break;
556
557 case HCI_EVENT_DISCONNECTION_COMPLETE:
558 handle = little_endian_read_16(packet,3);
559 if (handle == sco_handle){
560 sco_handle = 0;
561 hsp_state = HSP_W2_DISCONNECT_RFCOMM;
517
518 if (hs_outgoing_connection){
519 hs_outgoing_connection = 0;
520 hs_send_button_press = 1;
521 }
522
523 switch (hsp_state){
524 case HSP_W4_RFCOMM_CONNECTED:

--- 12 unchanged lines hidden (view full) ---

537 hsp_hs_callback(packet, size);
538 break;
539
540 case HCI_EVENT_DISCONNECTION_COMPLETE:
541 handle = little_endian_read_16(packet,3);
542 if (handle == sco_handle){
543 sco_handle = 0;
544 hsp_state = HSP_W2_DISCONNECT_RFCOMM;
562 printf(" HSP_W2_DISCONNECT_RFCOMM\n");
563 break;
564 }
565 break;
566 case RFCOMM_EVENT_CHANNEL_CLOSED:
545 break;
546 }
547 break;
548 case RFCOMM_EVENT_CHANNEL_CLOSED:
567 printf("RFCOMM channel closed\n");
568 hsp_hs_reset_state();
569 emit_event(HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE,0);
570 break;
571 default:
572 break;
573 }
574 hsp_run();
575}
576
577static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
578 switch (hci_event_packet_get_type(packet)){
579 case SDP_EVENT_QUERY_RFCOMM_SERVICE:
580 channel_nr = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet);
549 hsp_hs_reset_state();
550 emit_event(HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE,0);
551 break;
552 default:
553 break;
554 }
555 hsp_run();
556}
557
558static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
559 switch (hci_event_packet_get_type(packet)){
560 case SDP_EVENT_QUERY_RFCOMM_SERVICE:
561 channel_nr = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet);
581 printf("** Service name: '%s', RFCOMM port %u\n", sdp_event_query_rfcomm_service_get_name(packet), channel_nr);
562 log_info("** Service name: '%s', RFCOMM port %u", ve->service_name, channel_nr);
582 break;
583 case SDP_EVENT_QUERY_COMPLETE:
584 if (channel_nr > 0){
585 hsp_state = HSP_W4_RFCOMM_CONNECTED;
563 break;
564 case SDP_EVENT_QUERY_COMPLETE:
565 if (channel_nr > 0){
566 hsp_state = HSP_W4_RFCOMM_CONNECTED;
586 printf("RFCOMM create channel.\n");
567 log_info("RFCOMM create channel");
587 rfcomm_create_channel(packet_handler, remote, channel_nr, NULL);
588 break;
589 }
590 hsp_hs_reset_state();
568 rfcomm_create_channel(packet_handler, remote, channel_nr, NULL);
569 break;
570 }
571 hsp_hs_reset_state();
591 printf("Service not found, status %u.\n", sdp_event_query_complete_get_status(packet));
592 exit(0);
572 log_info("Service not found, status %u.", sdp_event_query_complete_get_status(packet));
593 break;
594 }
595}
596
597void hsp_hs_send_button_press(void){
598 hs_send_button_press = 1;
599 hsp_run();
600}
573 break;
574 }
575}
576
577void hsp_hs_send_button_press(void){
578 hs_send_button_press = 1;
579 hsp_run();
580}