This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software: Code Composer Studio
Hi:
I use TI-hiddemo of cc2564b of STM32. Before my device is paired and connected, I set the HID mode of the device to "Device", and then when the PC connects the device and matches it successfully, I save the "LinkKeyInfo"information of this connection with the PC in the flash of STM32,After the device restarts, the STM32 program will first check whether “LinkKeyInfo” is saved in the flash. If so, the device will set the HID mode to "Host". At this time, the device will use the subroutine "ConnectRemoteHIDDevice " to automatically connect the saved "LinkKeyInfo[index]. BD_ADDR", regardless of the PC system (for example: Windows 7 or Windows 8( Ver:1083 ) or Windows 8( Ver:1093 ))Everything can be connected properly. But when I rebooted my PC, at this time Windows 10 (Version 1803 Creator) can not connection to CC2564B with HID,However, windows 10 (version 1903 ) or Windows 7 can connect to cc2564b with hid.
After analyzing the data of HCI layer, the reason why windows 10 (version 1803 creator) can not connect to cc2564b with HID is that the l2ca channel on the computer side cannot be opened normally
My idea now is to go through "L2CA_Connect_Request "again, but" L2CA_Connect_Request "Connect_ Don't know how to write it?
The main problem is that the event "L2CA_Event_Callback" is not found in hiddemo of cc2564b application?
Please provide this aspect of the source code?
We can't provide source code of the BT stack. but let me see if our SW experts have ideas on a way forward.
Regards,
Travis
Hello,
HIDConnectRemoteDevice calls HID_Connect_Remote_Device which then calls L2CA_Connect_Request internally. Unfortunately we do not release this source code. The demo only has GAP event callback and HID event callbacks.
However I do see that we expose the L2CAPAPI which you can find in the include folder of the SDK. It looks like you call L2CA_Register_PSM to register your own L2CA_Event_Callback in your application. Refer to the attached example:
#define LOCAL_RECEIVE_BUFFER_SIZE 1024 static int ret_val; Server Side: static unsigned int L2CAP_PSMID; /* Register a Server to handle requests from remote devices. */ ret_val = L2CA_Register_PSM(BluetoothStackID, L2CAP_PSM_MINIMUM_PSM, L2CA_Event_Callback, 1); if(ret_val > 0) { /* Save the PSMID that will be needed to unregsiter the Server. */ L2CAP_PSMID = (unsigned int)ret_val; } else printf("L2CA_Register_PSM failed with %d\r\n", ret_val); Client Side: static Word_t CID; ret_val = L2CA_Connect_Request(BluetoothStackID, BD_ADDR, L2CAP_PSM_MINIMUM_PSM, L2CA_Event_Callback, (unsigned long)0); if(ret_val > 0) { CID = (Word_t)ret_val; printf("L2CAP_CID=%04X\r\n", CID); } else printf("L2CA_Connect_Request failed with %d\r\n", ret_val); /******************************************************************************/ /** L2CA_Event_Callback(unsigned int, L2CA_Event_Data_t *, unsigned long) **/ /******************************************************************************/ /** L2CA_Event_Callback Function. **/ /** **/ /** * NOTE * Since we are being called in the Context of another Thread it **/ /** is NOT polite (and error prone) to issue Windows GUI function **/ /** calls to the Main Window. Because of this we have developed **/ /** special functions that will post any GUI information to the **/ /** Main Thread to alleviate this problem. **/ /** * NOTE * The above mentioned thread context issue is not a limitation **/ /** of the Protocol Stack, it exists because Windows GUI calls are **/ /** NOT thread safe !!!! **/ /** **/ /******************************************************************************/ static void BTPSAPI L2CA_Event_Callback(unsigned int BluetoothStackID, L2CA_Event_Data_t *L2CA_Event_Data, unsigned long CallbackParameter) { int ret_val; int Length; Byte_t Identifier; Word_t CID; BD_ADDR_t BD_ADDR; L2CA_Config_Response_t ConfigResponse; L2CA_Config_Request_t ConfigRequest; if((BluetoothStackID) && (L2CA_Event_Data)) { switch(L2CA_Event_Data->L2CA_Event_Type) { case etConnect_Indication: printf("etConnect_Indication"); /* Someone is trying to Connect to us, so let's accept the */ /* Request by issuing a Connect Response. */ BD_ADDR = L2CA_Event_Data->Event_Data.L2CA_Connect_Indication->BD_ADDR; CID = L2CA_Event_Data->Event_Data.L2CA_Connect_Indication->LCID; Identifier = L2CA_Event_Data->Event_Data.L2CA_Connect_Indication->Identifier; ret_val = L2CA_Connect_Response(BluetoothStackID, BD_ADDR, Identifier, CID, L2CAP_CONNECT_RESPONSE_RESPONSE_SUCCESSFUL, 0); if(!ret_val) { /* Connect Response was issued successfully, so let's */ /* clear the Config Request and fill the approrpriate */ /* fields. */ memset(&ConfigRequest, 0, sizeof(L2CA_Config_Request_t)); /* Set the desired MTU. This will tell the remote device*/ /* what the Maximum packet size that are capable if */ /* receiving. */ ConfigRequest.Option_Flags = L2CA_CONFIG_OPTION_FLAG_MTU; ConfigRequest.InMTU = (Word_t)LOCAL_RECEIVE_BUFFER_SIZE; /* Send the Config Request to the Remote Ddvice. */ ret_val = L2CA_Config_Request(BluetoothStackID, CID, L2CAP_LINK_TIMEOUT_MAXIMUM_VALUE, &ConfigRequest); if(ret_val) { /* Config Request Error, so let's issue an error to */ /* the user and Delete the CID that we have already */ /* added to the List Box. */ printf(" Config Request: Function Error %d.", ret_val); } } else { /* Connect Response Error, so let's inform the user. */ printf(" Connect Response: Function Error %d.", ret_val); } break; case etConnect_Confirmation: printf("etConnect_Confirmation"); /* We have received a Positive or Negative Connection */ /* Response from a Connection Request that we issued */ /* earlier. */ CID = L2CA_Event_Data->Event_Data.L2CA_Connect_Confirmation->LCID; /* Let's determine if the Connection was accepted by the */ /* Remote side. */ if(L2CA_Event_Data->Event_Data.L2CA_Connect_Confirmation->Result == L2CAP_CONNECT_RESULT_CONNECTION_SUCCESSFUL) { /* Connection accepted, so inform the user. */ printf(" Connection Confirmed for CID: 0x%04X", CID); printf(" Sending Config Request."); /* Clear the Config Request and fill the approrpriate */ /* fields. */ memset(&ConfigRequest, 0, sizeof(L2CA_Config_Request_t)); /* Set the desired MTU. */ ConfigRequest.Option_Flags = L2CA_CONFIG_OPTION_FLAG_MTU; ConfigRequest.InMTU = (Word_t)LOCAL_RECEIVE_BUFFER_SIZE; /* Send the Config Request to the Remote DEvice. */ ret_val = L2CA_Config_Request(BluetoothStackID, CID, L2CAP_LINK_TIMEOUT_MAXIMUM_VALUE, &ConfigRequest); if(ret_val) { /* Error issuing Config Request, so let's delete the */ /* CID from the List Box and inform the User. */ printf(" Config Request: Function Error %d.", ret_val); } } else { /* Check to see if the Remote side has requested that the*/ /* Connect Response be pended (until some future point in*/ /* time). */ if(L2CA_Event_Data->Event_Data.L2CA_Connect_Confirmation->Result == L2CAP_CONNECT_RESULT_CONNECTION_PENDING) { printf(" Connect Confirmation Pending (CID: 0x%04X, Status: 0x%04X).", CID, L2CA_Event_Data->Event_Data.L2CA_Connect_Confirmation->Status); } else { /* Remote side Rejected the Connect Request for some */ /* reason, so let's inform the user and delete the CID*/ /* from the List Box. */ printf(" Connect Confirmation Neg (CID: 0x%04X, Result: 0x%04X).", CID, L2CA_Event_Data->Event_Data.L2CA_Connect_Confirmation->Result); } } break; case etConfig_Indication: printf("etConfig_Indication"); /* Remote Side has issued an L2CAP Connect Request and we */ /* are being notified of it. */ CID = L2CA_Event_Data->Event_Data.L2CA_Config_Indication->LCID; /* Zero all parameters in the Configuration response. */ memset(&ConfigResponse, 0, sizeof(L2CA_Config_Response_t)); Result = L2CAP_CONFIGURE_RESPONSE_RESULT_SUCCESS; /* If the remote has specified an MTU, then we must accept */ /* it. We will echo back the value that was received. */ if(L2CA_Event_Data->Event_Data.L2CA_Config_Indication->Option_Flags & L2CA_CONFIG_OPTION_FLAG_MTU) { ConfigResponse.Option_Flags |= L2CA_CONFIG_OPTION_FLAG_MTU; ConfigResponse.OutMTU = L2CA_Event_Data->Event_Data.L2CA_Config_Indication->OutMTU; } printf(" Sending Config Response: 0x%04X.", Result); ret_val = L2CA_Config_Response(BluetoothStackID, CID, Result, &ConfigResponse); if(ret_val) { /* Error Issuing Configuration Response so Delete the CID*/ /* from the List and inform the user. */ printf(" Config Response: Function Error %d.", ret_val); } break; case etConfig_Confirmation: printf("etConfig_Confirmation"); /* We have received a Configuration Confirmation from the */ /* remote side (in response to a Configuration Request that */ /* we issued). */ Result = L2CA_Event_Data->Event_Data.L2CA_Config_Confirmation->Result; CID = L2CA_Event_Data->Event_Data.L2CA_Config_Confirmation->LCID; /* Inform the user of what has happened. */ printf(" L2CA_Config_Confirmation (CID = 0x%04X, Result = 0x%04X).", CID, Result); /* Clear the new Request. */ memset(&ConfigRequest, 0, sizeof(L2CA_Config_Request_t)); /* If the Remote side has not accepted the Connect Request */ /* we have sent, then we need to see what they are */ /* suggesting. */ if(Result == L2CAP_CONFIGURE_RESPONSE_RESULT_FAILURE_UNACCEPTABLE_PARAMETERS) { /* If our parameters were not accepted, then we need to */ /* disconnect the link. */ L2CA_Disconnect_Request(BluetoothStackID, CID); } break; case etData_Indication: /* Remote Side has sent us Data so inform the user of the */ /* Data. */ CID = L2CA_Event_Data->Event_Data.L2CA_Data_Indication->CID; Length = L2CA_Event_Data->Event_Data.L2CA_Data_Indication->Data_Length; /* * NOTE * Received data is being dispatched to us. When */ /* this callback returns to the lower layer, the */ /* data will be released. So, if the received data*/ /* can't be processed in this callback, the data */ /* will have to be copied to a local buffer for */ /* future processing. */ printf("L2CA Data Received :(Bytes Read = %d, CID = 0x%04X).", L2CA_Event_Data->Event_Data.L2CA_Data_Indication->Data_Length, CID); break; case etData_Error_Indication: /* L2CAP Layer has determined there was a problem sending */ /* or receiving data, so the L2CAP Layer is notifying us. */ /* Simply inform the user of what has happened. */ CID = L2CA_Event_Data->Event_Data.L2CA_Data_Error_Indication->CID; printf(" L2CA_Data_Error_Indication: CID 0x%04X.", CID); break; case etChannel_Buffer_Empty_Indication: /* This callback event will be dispatched only after a */ /* buffer full situation has occurred. The buffer full */ /* indication occurs when there is no room in the lower */ /* layer to buffer an additional outgoing packet and is */ /* noted by the return value from L2CA_Data_Write(). */ printf("etChannel_Buffer_Empty_Indication"); break; case etTimeout_Indication: CID = L2CA_Event_Data->Event_Data.L2CA_Timeout_Indication->LCID; printf(" L2CA_Timeout_Indication (CID = 0x%04X).", CID); break; case etDisconnect_Indication: case etDisconnect_Confirmation: /* Either the remote or local side has requested termination*/ /* of the L2CAP Link, so we need to inform the user, delete */ /* the CID from the List Box, and Respond to the Disconnect */ /* Event (really only need to respond if there was a */ /* Disconnect Indication). */ if(L2CA_Event_Data->L2CA_Event_Type == etDisconnect_Indication) { CID = L2CA_Event_Data->Event_Data.L2CA_Disconnect_Indication->LCID; L2CA_Disconnect_Response(BluetoothStackID, CID); } else CID = L2CA_Event_Data->Event_Data.L2CA_Disconnect_Confirmation->LCID; printf(" Disconnected from: CID 0x%04X.", CID); break; } } }
Jesu
Hi Jesu:
Thank you for your reply. According to the above reply, my problem has been solved。
I now encounter a new problem. When my CC2564 device is connected to a PC computer, when the distance is greater than 10 meters, the two devices can't normally send data through HID. At this time, the Bluetooth connection between CC2564 and PC is still in the connection state. Now I keep the Bluetooth distance greater than 10 meters and wait for more than 20s before Bluetooth disconnection of two devices occurs. To solve this problem, after the Bluetooth connection between the two devices is established, I use “HCI_Write_Link_Supervision_Timeout(BluetoothStackID, Connection_Handle, 0x160, &status, &Connect_Status);”The monitoring time of LSTO is adjusted. The value returned by this program is 0, but the disconnection time is still about 20s. My question is how to shorten the monitoring time, so that the Bluetooth of the two devices can be disconnected immediately if the long-distance communication fails?
I believe HCI_Write_Link_Supervision_Timeout is the right command to accomplish what you want here. Have you tried setting it to 0 instead of 0x160?
Jesu
Hi,Jesu:
I have tried to set different values of Link_Supervision_Timeout , and the disconnection time of the two devices is still about 20s。At the same time, I tried to use the program of “HCI_Switch_Role”to switch between master and slave, but the problem still exists.What should I change now? Thank you for your guidance!
Hmmm. I'm not sure what could be the issue with the supervision timeout then. Do you mind capturing FW logs so I can see what is going on?
https://processors.wiki.ti.com/index.php/CC256x_Logger_User_Guide#Setting_up_the_Bluetooth_logger
Jesu
Hi,Jesu:
According to what you said, I have captured the data. The whole process is divided into three parts: in the first part, I turn on the device of cc2564b , and then use the PC to actively connect the device of cc2564b . After connecting, I shut down the device of cc2564b. In the second part, I turn on the device of cc2564b, and then the device of cc2564b will automatically connect to the PC. In the third part, I set the distance between PC and the device of cc2564b at a distance of 20m. At this time, the two devices can no longer communicate normally. At this time, the time is the picture time below.
CC2564B Console Uart Log: /cfs-file/__key/communityserver-discussions-components-files/538/8321.Console_5F00_USART-Log.txt
CC2564B TXDebug log: /cfs-file/__key/communityserver-discussions-components-files/538/CC2564B_5F00_TXDebug.zip
Hi,Jesu:
On the basis of providing the above log, I found another problem. I used "ret_val=HCI_Write_Link_Supervision_Timeout(BluetoothStackID, Connection_Handle, 0x1000, &status, &Connect_Status);"to modify the timeout. The return value of the secondary function is" 0 ",I don't care if "Link_Supervision_Timeout" is adjusted to a different value, but I use "Link_Supervision_Timeout” to read timeout, The value read out by timeout is always "0x7000".
Hello,
Thanks for sending the FW logs. I only see 1 HCI_Write_Link_Supervision_Timeout and it attempts to set it to 20 seconds (0x7d00).
I don't see your call in the FW logs:
ret_val=HCI_Write_Link_Supervision_Timeout(BluetoothStackID, Connection_Handle, 0x1000, &status, &Connect_Status);
Could you make sure you capture logs when this command is sent?
Judging by the command above you are trying to set the timeout to 2.56 seconds. I attached the supervision timeout table from BT spec for reference.
Jesu
Hi,Jesu:
I have solved this problem. I found that after sending the modified timeout time, the return value of "statusresult" is "0x0c". By solving this status value, I successfully modified the timeout time。