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.

How long can i write, using Blob write From iphone To 2540?

Other Parts Discussed in Thread: CC2540, BLE-STACK, CC2650

How long can i write, using Blob write From iphone To 2540?

i use iphone write a Characteristic about 252 byte(write Long Characteristic Value), but iphone return unknow Error, MayBe the 2540 is timeout?

 short msg length(but can write only 90 byte) have no problem. does the 2540 have some limit to Blob write?

 

  • I use sniffer get the error, PERPARE_QUEUE_FULL, but how to change the Queue's length?

  • Hi Guo,

    What application is running on the peripheral device? Can you supply more of the sniffer log?

    Does this happen with all Long writes or just (too) long ones?

    Best regards,
    Aslak 

  • I use My iphone4S write(blob write) some data to cc2540, but when i write a data which larger than 90Byte, Iphone4s will return unknow error.

    sniffer log is here, the error packet is PktNumber = 406, Thanks.:)

     7558.321312.psd

    my program is change from KeyFobDemo.

    config:


    // Delay between power-up and starting advertising (in ms)
    #define STARTDELAY                    500

    // How often to check battery voltage (in ms)
    #define BATTERY_CHECK_PERIOD          10000

    // Whether to enable automatic parameter update request when a connection is formed
    #define DEFAULT_ENABLE_UPDATE_REQUEST         FALSE

    // Use limited discoverable mode to advertise for 30.72s, and then stop, or
    // use general discoverable mode to advertise indefinitely
    #define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_LIMITED
    //#define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL

    // Minimum connection interval (units of 1.25ms, 80=100ms) if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80

    // Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800

    // Slave latency to use if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_SLAVE_LATENCY         0

    // Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_CONN_TIMEOUT          3000

     

    profile:

    static bStatus_t SpiProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                            uint8 *pValue, uint8 len, uint16 offset )
    {
        bStatus_t status = SUCCESS;
        uint8 notifyApp = 0xFF;
        uint8 *pCurValue = NULL;
       uint16 *pWriteLenPtr = NULL;
       
        // If attribute permissions require authorization to write, return error
        if ( gattPermitAuthorWrite( pAttr->permissions ) )
        {
            // Insufficient authorization
            return ( ATT_ERR_INSUFFICIENT_AUTHOR );
        }

        if ( pAttr->type.len == ATT_BT_UUID_SIZE )
        {
            // 16-bit UUID
            uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
            switch ( uuid )
            {
                case GATT_CLIENT_CHAR_CFG_UUID:
                    status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                            offset, GATT_CLIENT_CFG_NOTIFY );
                    break;
                   
                case SPIPROFILE_WRITE_UUID:
                    //Write the value
            pCurValue = (uint8 *)pAttr->pValue;   
            memcpy(pCurValue+offset, pValue, len);

                    break;

                default:
                    // Should never get here! (characteristics 2 and 4 do not have write permissions)
                    status = ATT_ERR_ATTR_NOT_FOUND;
                    break;
            }
        }
        else
        {
            // 128-bit UUID
            status = ATT_ERR_INVALID_HANDLE;
        }
       
        // If a charactersitic value changed then callback function to notify application of change
        if ( (notifyApp != 0xFF ) && spiProfile_AppCBs && spiProfile_AppCBs->pfnSpiProfileChange )
        {
            spiProfile_AppCBs->pfnSpiProfileChange( notifyApp ); 
        }
       
        return ( status );
    }

  •  

    Test Code:

        NSMutableData *d = [[NSMutableData alloc] init];
        Byte data = 'A';
        for (int i = 0; i<100; i++) {     // 90 is Ok, more than 90 will return error
            data = 'A' + (i%26);
            [d appendBytes:&data length:1];
        }
        
        [[TIBLECBKeyfob sharedData] writeValue:0xfff0 characteristicUUID:0xfff4 p:[TIBLECBKeyfob sharedSceneryData].activePeripheral data:d];

    writeValue Function:

    -(void) writeValue:(int)serviceUUID characteristicUUID:(int)characteristicUUID p:(CBPeripheral *)p data:(NSData *)data {
        UInt16 s = [self swap:serviceUUID];
        UInt16 c = [self swap:characteristicUUID];
        NSData *sd = [[NSData alloc] initWithBytes:(char *)&s length:2];
        NSData *cd = [[NSData alloc] initWithBytes:(char *)&c length:2];
        CBUUID *su = [CBUUID UUIDWithData:sd];
        [sd release];
        CBUUID *cu = [CBUUID UUIDWithData:cd];
        [cd release];
       
        CBService *service = [self findServiceFromUUID:su p:p];
        if (!service) {
            printf("Could not find service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:su],[self UUIDToString:p.UUID]);
            return;
        }
        CBCharacteristic *characteristic = [self findCharacteristicFromUUID:cu service:service];
        if (!characteristic) {
            printf("Could not find characteristic with UUID %s on service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:cu],[self CBUUIDToString:su],[self UUIDToString:p.UUID]);
            return;
        }
       
        CBCharacteristicWriteType writeType = CBCharacteristicWriteWithResponse;
        [p writeValue:data forCharacteristic:characteristic type:writeType];
    }

     

     

     

  • Hi Guo,

    It certainly looks like the received data isn't handled until the write is finished, and the internal buffer gets filled up.

    Unfortunately there isn't much that can be done about this until the next BLE stack release, if this will be addressed at all. There isn't too much RAM to go around in the first place. I will take this up with the stack developers.

    A workaround is to simply split up the writes at the level of the application.

    If you have a log of a successful <90 bytes blob write, could you post it?

    Best regards,
    Aslak 

  • Thank you very much,:)

    this is the log of successful blob write. Blob write is 417 to 442

    413-416 is my program write a data length to device, not the Blob write packet 

    3817.OK90.psd

  • Hi, Aslak, I'm using BLE 1.3.2, and found the same behavior. If I tried to write more than 90/91 bytes, I got error 9 on iPhone 5 with iOS 6 on it. Error 9 is ATT_ERR_PREPARE_QUEUE_FULL. 

    Is this solved in BLE 1.3.2? Or is there any configuration for me to increase the queue size?

    Thank you very much!

  • No, they have not changed this. If only they would deliver each packet as it came it, there would not be an issue.

  • BLE stack 1.4 seems to have the same limitation:
    With sniffer i see >90 bytes write blob still responses with ErrorCode PREPARE_QUEUE_FULL=0x09.

    So this limit was also not fixed in the now acual BLE stack 1.4 ?
    Is it planned to be fixed in future ?

  • Is there any update on this issue?

  • Any plan to get it fixed? I will appreciate if some TI member can respond.

    Thanks

  • Hi,

    You can try to increase the size of the prepare queue by calling 

    GATTServApp_SetParameter(GATT_PARAM_NUM_PREPARE_WRITES, 1, &u8VarWithNumber);

    This should increase the long write size. The number is 5 by default. I would advise against increasing this excessively since it allocates memory and keeps it.

    Best regards,
    Aslak

  • Thanks Aslak,

    It worked!

  • Thanks Aslak,

    This is working for me as well!

  • Still having the same problem with BLE-STACK 2.0.0 on CC2650.