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.

using UUID instead of specific PORTnumber for connection? MSP430/bluetopia/SPP

Hi,

i am building a hardware to communicate with an android phone.

for my first prototype i used an AT-command Bluetooth-Module, and the module managed the connection.
it uses the default UUID for SPP-Profile, and everything works fine with my Android-App.

now i am changing the hardware to MSP430+PAN1326+Bluetopia.
works fine so far with my app too.
i open a connection with the right port to communicate to the App...

now the Question/Problem:
a) i would like to use a specific UUID for my application, to prevent misusage.
b) the other thing is, i did not specify any specific port in the app. i just tried a few ports for the connection, and found out, that port 5 and 6 work. no i am affraid, that it might not work on other phones, if the app gets another port from the OS!?
as i saw on my first prototype with the at-command-module, it seems not to be necessary to specify a port. it seems to work when they just use the same UUID!?

thanks for your help!

  • Daniel,

    To connect to the SPP Server, you must specify the port number. 

    The SPP port will differ for different phones. To make sure you connect to the right port, perform an SDP Query for the SPP UUID. The function that you will need to look at is SDP_Service_Search_Attribute_Request and retrieve the correct port from the Result.

    Thanks,

    Stonestreet One.

  • Hi,
    thanks for this reply, it was a great help for me (also the backgroundinfo how it works).

    i found this thread where the implementation of this part is discussed incl. the necessary code for stellaris:
    http://e2e.ti.com/support/low_power_rf/f/660/p/169706/644840.aspx

    i tried to implement this code in my SPPDemo for MSP430 (CCS5), but it is not working...
    i always get this anoying error:
    error #10234-D: unresolved symbols remain
    error #10010: errors encountered during linking; "SPPDemo.out" not built

    i included the SDPAPI.h and copied the three methods directly into the SPPDemo.c. (also tried with own header-file - same result) 

    could you help me out with a working sample?

    Edit:
    now i found out more details, which lines generate the error:
    ASSIGN_UUID_16(SDPUUIDEntry.UUID_Value.UUID_16, 0x11, 0x01);
    ASSIGN_UUID_16_TO_UUID_128(UUID_128, SDP_Data_Element1->SDP_Data_Element.UUID_16);
    ASSIGN_UUID_32_TO_UUID_128(UUID_128, SDP_Data_Element1->SDP_Data_Element.UUID_32);
    i commented out those 3 lines and then the compiling and linking finishes without an error.
    but it will not work without those lines :o) 

    EDIT2:
    ok, i think i got it...
    in the BTBTypes.h is a remark, that those old methods were renamed to ASSIGN_SDP_UUID_16  ....

    another question:
    the SDP Query works now...
    but i found out, that after the SDP Query it takes some time (about 30sek). until i can connect to my server as usual. it looks like there is anything left open and i cannot connect until timeout!?  is there anything to close after the SDP_Search?

  • Daniel,

    Take a look at the code below. 

    1. Special SDP Callback that calls the parser function when you request the attribute that has RFCOMM server port data.

       static void BTPSAPI RFC_SDP_EventCallback(
               unsigned int BluetoothStackID,
               unsigned int SDPRequestID,
               SDP_Response_Data_t *SDP_Response_Data,
               unsigned long CallbackParameter)

     

    2. Function that parses out the RFCOMM port number for the service

    ExtractRFCOMMPortNumber(SDP_Service_Search_Attribute_Response_Data_t *SDPServiceSearchAttributeResponse, int *RFCOMMPortList

     

    3. Trigger function that you need to call from your code which takes the Inquiry Index as Input(You must do an Inquiry and find the remote device first).

    static int SDPRequest(ParameterList_t *TempParam);

    Code:

    static int ExtractRFCOMMPortNumber(SDP_Service_Search_Attribute_Response_Data_t *SDPServiceSearchAttributeResponse, int *PortList);
    static void BTPSAPI RFC_SDP_EventCallback(unsigned int BluetoothStackID, unsigned int SDPRequestID, SDP_Response_Data_t *SDP_Response_Data, unsigned long CallbackParameter);

    static void BTPSAPI RFC_SDP_EventCallback(unsigned int BluetoothStackID, unsigned int SDPRequestID, SDP_Response_Data_t *SDP_Response_Data, unsigned long CallbackParameter)
    {
    int Index;
    //int ServerPort;
    int RFCOMMPortList[30];

    /* First, check to see if the required parameters appear to be */
    /* semi-valid. */
    if((SDP_Response_Data != NULL) && (BluetoothStackID))
    {
    /* The parameters appear to be semi-valid, now check to see what */
    /* type the incoming Event is. */
    switch(SDP_Response_Data->SDP_Response_Data_Type)
    {
    case rdTimeout:
    /* A SDP Timeout was received, display a message indicating */
    /* this. */
    Display(("\r\n"));
    Display(("SDP Timeout Received (Size = 0x%04X).\r\n", sizeof(SDP_Response_Data_t)));
    break;
    case rdConnectionError:
    /* A SDP Connection Error was received, display a message */
    /* indicating this. */
    Display(("\r\n"));
    Display(("SDP Connection Error Received (Size = 0x%04X).\r\n", sizeof(SDP_Response_Data_t) ));
    break;
    case rdErrorResponse:
    /* A SDP error response was received, display all relevant */
    /* information regarding this event. */
    Display(("\r\n"));
    Display(("SDP Error Response Received (Size = 0x%04X) - Error Code: %d.\r\n", sizeof(SDP_Response_Data_t), SDP_Response_Data->SDP_Response_Data.SDP_Error_Response_Data.Error_Code));
    break;
    case rdServiceSearchResponse:
    /* A SDP Service Search Response was received, display all */
    /* relevant information regarding this event */
    Display(("\r\n"));
    Display(("SDP Service Search Response Received (Size = 0x%04X) - Record Count: %d\r\n", sizeof(SDP_Response_Data_t), SDP_Response_Data->SDP_Response_Data.SDP_Service_Search_Response_Data.Total_Service_Record_Count ));

    /* First, check to see if any SDP Service Records were */
    /* found. */
    if(SDP_Response_Data->SDP_Response_Data.SDP_Service_Search_Response_Data.Total_Service_Record_Count)
    {
    Display(("Record Handles:\r\n"));

    for(Index = 0; (Word_t)Index < SDP_Response_Data->SDP_Response_Data.SDP_Service_Search_Response_Data.Total_Service_Record_Count; Index++)
    {
    Display(("Record %u: 0x%08X\r\n", (Index + 1), (unsigned int)SDP_Response_Data->SDP_Response_Data.SDP_Service_Search_Response_Data.Service_Record_List[Index] ));

    }
    }
    else
    Display(("No SDP Service Records Found.\r\n"));
    break;
    case rdServiceAttributeResponse:
    /* A SDP Service Attribute Response was received, display */
    /* all relevant information regarding this event */
    Display(("\r\n"));
    Display(("SDP Service Attribute Response Received (Size = 0x%04X)\r\n", sizeof(SDP_Response_Data_t) ));

    //DisplaySDPAttributeResponse((&SDP_Response_Data->SDP_Response_Data.SDP_Service_Attribute_Response_Data, 0));
    break;
    case rdServiceSearchAttributeResponse:
    /* A SDP Service Search Attribute Response was received, */
    /* display all relevant information regarding this event */
    Display(("\r\n"));
    Display(("SDP Service Search Attribute Response Received (Size = 0x%04X)\r\n", sizeof(SDP_Response_Data_t) ));
    BTPS_MemInitialize(RFCOMMPortList, 0, sizeof(RFCOMMPortList));

    /* Call only when you queried for Attribute ID 0x04 */
    if(ExtractRFCOMMPortNumber(&SDP_Response_Data->SDP_Response_Data.SDP_Service_Search_Attribute_Response_Data, RFCOMMPortList) == 0)
    {
    Index = 0;

    while(RFCOMMPortList[Index])
    {
    Display(("RFCOMM Server Port Found at: %d", RFCOMMPortList[Index] ));

    Index++;
    }
    }
    else
    {
    Display(("No RFCOMM Server found"));
    }


    //DisplaySDPSearchAttributeResponse((&SDP_Response_Data->SDP_Response_Data.SDP_Service_Search_Attribute_Response_Data));
    break;
    default:
    /* An unknown/unexpected SDP event was received. */
    Display(("\r\n"));
    Display(("Unknown SDP Event.\r\n"));
    break;
    }
    }
    else
    {
    /* There was an error with one or more of the input parameters. */
    Display(("\r\n"));
    Display(("SDP callback data: Response_Data = NULL.\r\n"));
    }
    }


    static int ExtractRFCOMMPortNumber(SDP_Service_Search_Attribute_Response_Data_t *SDPServiceSearchAttributeResponse, int *RFCOMMPortList)
    {
    int NumberOfAttributes;
    int NumberOfRecords;
    int RFCOMMChannel;
    int RetVal=-1;
    int Index;
    int RecordIndex;
    int NumberElements;
    int PortCount=0;
    UUID_128_t UUID_128;
    UUID_128_t RFCOMM_UUID;
    SDP_Data_Element_t *SDP_Data_Element;
    SDP_Data_Element_t *SDP_Data_Element1;

    SDP_ASSIGN_RFCOMM_UUID_128(RFCOMM_UUID);

    /* This is a response received when we queried Attribute ID 0x04 */
    NumberOfRecords = SDPServiceSearchAttributeResponse->Number_Service_Records;

    Display(("Number of Records: %d ", NumberOfRecords ));

    for(RecordIndex = 0; RecordIndex < NumberOfRecords; RecordIndex++)
    {
    NumberOfAttributes = SDPServiceSearchAttributeResponse->SDP_Service_Attribute_Response_Data[RecordIndex].Number_Attribute_Values;

    if(NumberOfAttributes)
    {
    SDP_Data_Element = SDPServiceSearchAttributeResponse->SDP_Service_Attribute_Response_Data[RecordIndex].SDP_Service_Attribute_Value_Data[0].SDP_Data_Element;

    if((SDP_Data_Element->SDP_Data_Element_Type == deSequence) && (SDP_Data_Element->SDP_Data_Element_Length))
    {
    /* Data Element Sequence Exists, now */
    /* let's loop through the Data Element */
    /* Sequence. */
    for(Index=0; Index < SDP_Data_Element->SDP_Data_Element_Length;Index++)
    {
    if(((SDP_Data_Element1 = &(SDP_Data_Element->SDP_Data_Element.SDP_Data_Element_Sequence[Index])) != NULL) && (SDP_Data_Element1->SDP_Data_Element_Type == deSequence) && ((NumberElements = SDP_Data_Element1->SDP_Data_Element_Length) > 0) && ((SDP_Data_Element1 = SDP_Data_Element1->SDP_Data_Element.SDP_Data_Element_Sequence) != NULL))
    {
    if((SDP_Data_Element1->SDP_Data_Element_Type == deUUID_16) || (SDP_Data_Element1->SDP_Data_Element_Type == deUUID_32) || (SDP_Data_Element1->SDP_Data_Element_Type == deUUID_128))
    {
    /* Initialize the BASE UUID. */
    SDP_ASSIGN_BASE_UUID(UUID_128);

    switch(SDP_Data_Element1->SDP_Data_Element_Type)
    {
    case deUUID_16:
    /* First normal-lize the*/
    /* 16 Bit UUID to 128 */
    /* Bits. */
    ASSIGN_SDP_UUID_16_TO_SDP_UUID_128(UUID_128, SDP_Data_Element1->SDP_Data_Element.UUID_16);
    break;
    case deUUID_32:
    /* First normal-lize the*/
    /* 32 Bit UUID to 128 */
    /* Bits. */
    ASSIGN_SDP_UUID_32_TO_SDP_UUID_128(UUID_128, SDP_Data_Element1->SDP_Data_Element.UUID_32);
    break;
    case deUUID_128:
    /* Simply assign the */
    /* 128 Bit UUID to the */
    /* UUID value. */
    UUID_128 = SDP_Data_Element1->SDP_Data_Element.UUID_128;
    break;
    }

    /* Now let's check to see if */
    /* there is a match to RFCOMM */
    if((COMPARE_UUID_128(RFCOMM_UUID, UUID_128)) && (NumberElements > 1))
    {
    if(SDP_Data_Element1[1].SDP_Data_Element_Type == deUnsignedInteger1Byte)
    {
    RFCOMMChannel = SDP_Data_Element1[1].SDP_Data_Element.UnsignedInteger1Byte;

    /* Add server port to return data */
    RFCOMMPortList[PortCount] = RFCOMMChannel;
    PortCount++;
    RetVal = 0;
    }
    }
    }
    else
    {
    /* Some unknown Protocol */
    /* Descriptor, so just ignore */
    /* it. */
    }
    }
    }
    }
    }

    }

    return(RetVal);
    }

    static int SDPRequest(ParameterList_t *TempParam)
    {
    int Result;
    int ret_val;
    SDP_UUID_Entry_t SDPUUIDEntry;
    SDP_Attribute_ID_List_Entry_t AttributeID;

    /* First, check that valid Bluetooth Stack ID exists. */
    if(BluetoothStackID)
    {
    /* Make sure that all of the parameters required for this function*/
    /* appear to be at least semi-valid. */
    if((TempParam) && (TempParam->NumberofParameters > 0) && (TempParam->Params[0].intParam) && (NumberofValidResponses) && (TempParam->Params[0].intParam <= NumberofValidResponses) && (!COMPARE_NULL_BD_ADDR(InquiryResultList[(TempParam->Params[0].intParam - 1)])))
    {

    SDPUUIDEntry.SDP_Data_Element_Type = deUUID_16;
    SDP_ASSIGN_SERIAL_PORT_PROFILE_UUID_16(SDPUUIDEntry.UUID_Value.UUID_16);

    AttributeID.Attribute_Range = (Boolean_t)FALSE;
    AttributeID.Start_Attribute_ID = 4;
    AttributeID.End_Attribute_ID = 0;
    Result = SDP_Service_Search_Attribute_Request(BluetoothStackID, InquiryResultList[(TempParam->Params[0].intParam - 1)], 1, &SDPUUIDEntry, 1, &AttributeID, RFC_SDP_EventCallback, 0);

    /* Check the return value of the submitted command for success.*/
    if(Result > 0)
    {
    /* Display a messsage indicating that Remote Name request */
    /* was initiated successfully. */
    Display(("Request ID %d.\r\n", Result));

    /* Flag success to the caller. */
    ret_val = 0;
    }
    else
    {
    /* Display a message indicating that an error occured while */
    /* initiating the Remote Name request. */
    DisplayFunctionError("Failed to Request Services", Result);

    ret_val = FUNCTION_ERROR;
    }
    }
    else
    {
    /* One or more of the necessary parameters is/are invalid. */
    DisplayUsage("SDPRequest [Inquiry Index]");

    ret_val = INVALID_PARAMETERS_ERROR;
    }
    }
    else
    {
    /* No valid Bluetooth Stack ID exists. */
    ret_val = INVALID_STACK_ID_ERROR;
    }

    return(ret_val);
    }

  • yes, this looks like the code i already implemented.

    is there any change to the code i posted behind the link?

    is there a fix to close the SDP-connection before timeout?

  • Daniel,

    Yes the post that you refer to use as deprecated functions that we do not support anymore. Please use the updated code. You should not see any compile errors. 

    I'm not sure what you refer by "fix to close the SDP-connection before timeout". Do you want to cancel the SDP_Service_Search_Attribute_Request before completion? If so you can use the SDP_Cancel_Service_Request function?

  • hi,

    this "new" code also works fine and gives me the correct Portnumber!

    there is no more need to cancel the service request, it seems to finish normal, and i can send my string imediately after the sdp-request without any cancel request...

    thanks..