att_server.c (969a5bba9383f568af3db3db28fba4f765336dc6) att_server.c (cbbb12d994bd0c91688de48a85bc8d2e42a809ed)
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

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

499
500 hci_con_handle_t request_con_handle = HCI_CON_HANDLE_INVALID;
501 while (1){
502 hci_connections_get_iterator(&it);
503 while(btstack_linked_list_iterator_has_next(&it)){
504 hci_connection_t * connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it);
505 att_server_t * att_server = &connection->att_server;
506
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

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

499
500 hci_con_handle_t request_con_handle = HCI_CON_HANDLE_INVALID;
501 while (1){
502 hci_connections_get_iterator(&it);
503 while(btstack_linked_list_iterator_has_next(&it)){
504 hci_connection_t * connection = (hci_connection_t *) btstack_linked_list_iterator_next(&it);
505 att_server_t * att_server = &connection->att_server;
506
507 if (!btstack_linked_list_empty(&att_server->can_send_now_clients)){
507 // handle indications first
508 if (!btstack_linked_list_empty(&att_server->indication_requests) && att_server->value_indication_handle == 0){
508 if (can_send_now){
509 if (can_send_now){
509 btstack_context_callback_registration_t * client = (btstack_context_callback_registration_t*) att_server->can_send_now_clients;
510 btstack_linked_list_remove(&att_server->can_send_now_clients, (btstack_linked_item_t *) client);
510 btstack_context_callback_registration_t * client = (btstack_context_callback_registration_t*) att_server->indication_requests;
511 btstack_linked_list_remove(&att_server->indication_requests, (btstack_linked_item_t *) client);
511 client->callback(client->context);
512 can_send_now = att_dispatch_server_can_send_now(att_server->connection.con_handle);
512 client->callback(client->context);
513 can_send_now = att_dispatch_server_can_send_now(att_server->connection.con_handle);
514 // track if there's more to send, but keep iterating - only true if callee didn't send indication
515 if (request_con_handle == HCI_CON_HANDLE_INVALID && att_server->value_indication_handle == 0 && !btstack_linked_list_empty(&att_server->indication_requests)){
516 request_con_handle = att_server->connection.con_handle;
517 }
518 } else {
519 // can_send_now == 0
520 att_dispatch_server_request_can_send_now_event(att_server->connection.con_handle);
521 return;
522 }
523 }
524
525 // then notifications
526 if (!btstack_linked_list_empty(&att_server->notification_requests)){
527 if (can_send_now){
528 btstack_context_callback_registration_t * client = (btstack_context_callback_registration_t*) att_server->notification_requests;
529 btstack_linked_list_remove(&att_server->notification_requests, (btstack_linked_item_t *) client);
530 client->callback(client->context);
531 can_send_now = att_dispatch_server_can_send_now(att_server->connection.con_handle);
513 // track if there's more to send, but keep iterating
532 // track if there's more to send, but keep iterating
514 if (request_con_handle == HCI_CON_HANDLE_INVALID && !btstack_linked_list_empty(&att_server->can_send_now_clients)){
533 if (request_con_handle == HCI_CON_HANDLE_INVALID && !btstack_linked_list_empty(&att_server->notification_requests)){
515 request_con_handle = att_server->connection.con_handle;
516 }
517 } else {
518 // can_send_now == 0
519 att_dispatch_server_request_can_send_now_event(att_server->connection.con_handle);
520 return;
521 }
522 }

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

565 if (!att_server) break;
566
567 // handle value indication confirms
568 if (packet[0] == ATT_HANDLE_VALUE_CONFIRMATION && att_server->value_indication_handle){
569 btstack_run_loop_remove_timer(&att_server->value_indication_timer);
570 uint16_t att_handle = att_server->value_indication_handle;
571 att_server->value_indication_handle = 0;
572 att_handle_value_indication_notify_client(0, att_server->connection.con_handle, att_handle);
534 request_con_handle = att_server->connection.con_handle;
535 }
536 } else {
537 // can_send_now == 0
538 att_dispatch_server_request_can_send_now_event(att_server->connection.con_handle);
539 return;
540 }
541 }

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

584 if (!att_server) break;
585
586 // handle value indication confirms
587 if (packet[0] == ATT_HANDLE_VALUE_CONFIRMATION && att_server->value_indication_handle){
588 btstack_run_loop_remove_timer(&att_server->value_indication_timer);
589 uint16_t att_handle = att_server->value_indication_handle;
590 att_server->value_indication_handle = 0;
591 att_handle_value_indication_notify_client(0, att_server->connection.con_handle, att_handle);
592 att_dispatch_server_request_can_send_now_event(att_server->connection.con_handle);
573 return;
574 }
575
576 // directly process command
577 // note: signed write cannot be handled directly as authentication needs to be verified
578 if (packet[0] == ATT_WRITE_COMMAND){
579 att_handle_request(&att_server->connection, packet, size, 0);
580 return;

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

868 att_set_write_callback(att_server_write_callback);
869
870}
871
872void att_server_register_packet_handler(btstack_packet_handler_t handler){
873 att_client_packet_handler = handler;
874}
875
593 return;
594 }
595
596 // directly process command
597 // note: signed write cannot be handled directly as authentication needs to be verified
598 if (packet[0] == ATT_WRITE_COMMAND){
599 att_handle_request(&att_server->connection, packet, size, 0);
600 return;

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

888 att_set_write_callback(att_server_write_callback);
889
890}
891
892void att_server_register_packet_handler(btstack_packet_handler_t handler){
893 att_client_packet_handler = handler;
894}
895
896
897// to be deprecated
876int att_server_can_send_packet_now(hci_con_handle_t con_handle){
898int att_server_can_send_packet_now(hci_con_handle_t con_handle){
877 return att_dispatch_server_can_send_now(con_handle);
899 return att_dispatch_server_can_send_now(con_handle);
878}
879
900}
901
902int att_server_register_can_send_now_callback(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle){
903 return att_server_request_to_send_notification(callback_registration, con_handle);
904}
905
880void att_server_request_can_send_now_event(hci_con_handle_t con_handle){
906void att_server_request_can_send_now_event(hci_con_handle_t con_handle){
881 log_debug("att_server_request_can_send_now_event 0x%04x", con_handle);
882 att_client_waiting_for_can_send_registration.callback = &att_emit_can_send_now_event;
907 att_client_waiting_for_can_send_registration.callback = &att_emit_can_send_now_event;
883 att_server_register_can_send_now_callback(&att_client_waiting_for_can_send_registration, con_handle);
908 att_server_request_to_send_notification(&att_client_waiting_for_can_send_registration, con_handle);
884}
909}
910// end of deprecated
885
911
886int att_server_register_can_send_now_callback(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle){
912int att_server_request_to_send_notification(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle){
887 att_server_t * att_server = att_server_for_handle(con_handle);
888 if (!att_server) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
913 att_server_t * att_server = att_server_for_handle(con_handle);
914 if (!att_server) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
889 btstack_linked_list_add_tail(&att_server->can_send_now_clients, (btstack_linked_item_t*) callback_registration);
915 btstack_linked_list_add_tail(&att_server->notification_requests, (btstack_linked_item_t*) callback_registration);
890 att_dispatch_server_request_can_send_now_event(con_handle);
891 return ERROR_CODE_SUCCESS;
892}
893
916 att_dispatch_server_request_can_send_now_event(con_handle);
917 return ERROR_CODE_SUCCESS;
918}
919
920int att_server_request_to_send_indication(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle){
921 att_server_t * att_server = att_server_for_handle(con_handle);
922 if (!att_server) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
923 btstack_linked_list_add_tail(&att_server->indication_requests, (btstack_linked_item_t*) callback_registration);
924 att_dispatch_server_request_can_send_now_event(con_handle);
925 return ERROR_CODE_SUCCESS;
926}
927
894int att_server_notify(hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t *value, uint16_t value_len){
895 att_server_t * att_server = att_server_for_handle(con_handle);
896 if (!att_server) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
897
898 if (!att_dispatch_server_can_send_now(con_handle)) return BTSTACK_ACL_BUFFERS_FULL;
899
900 l2cap_reserve_packet_buffer();
901 uint8_t * packet_buffer = l2cap_get_outgoing_buffer();

--- 23 unchanged lines hidden ---
928int att_server_notify(hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t *value, uint16_t value_len){
929 att_server_t * att_server = att_server_for_handle(con_handle);
930 if (!att_server) return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
931
932 if (!att_dispatch_server_can_send_now(con_handle)) return BTSTACK_ACL_BUFFERS_FULL;
933
934 l2cap_reserve_packet_buffer();
935 uint8_t * packet_buffer = l2cap_get_outgoing_buffer();

--- 23 unchanged lines hidden ---