Beispiel #1
0
/*-----------------------------------------------------------------------------------
 * Creates an empty mailbox.
 */
err_t sys_mbox_new( /*@special@*/ /*@out@*/ sys_mbox_t *mbox, /*@unused@*/int size ) /*@allocates *mbox@*/  /*@defines **mbox@*/
{
    e_mailbox_t* embox = malloc_named("LWIP_MBOX", sizeof(e_mailbox_t));
    /*@-noeffect@*/
    (void) size; /* unused parameter */
    /*@+noeffect@*/
    embox->buffer = malloc_named("LWIP_MBOX", archMESG_QUEUE_LENGTH*sizeof(void *));
    OS_CreateMB(&embox->mbox, sizeof(void *), archMESG_QUEUE_LENGTH, embox->buffer);
    *mbox = embox;
    /*@-compdef@*/ /* Lint doesnt realise allocation has occurred */
    return ERR_OK;
    /*@+compdef@*/
}
Beispiel #2
0
wiced_result_t bt_packet_pool_dynamic_allocate_packet( bt_packet_t** packet, uint32_t header_size, uint32_t data_size )
{
    if ( packet == NULL )
    {
        return WICED_BT_BADARG;
    }

    *packet = (bt_packet_t*)malloc_named( "bt_packet_pool", header_size + data_size + sizeof(bt_packet_t) - 1 );
    if ( *packet == NULL )
    {
        return WICED_BT_OUT_OF_HEAP_SPACE;
    }

    (*packet)->node.prev   = NULL;
    (*packet)->node.next   = NULL;
    (*packet)->node.data   = (void*)(*packet);
    (*packet)->pool        = DYNAMIC_PACKET_POOL;
    (*packet)->owner       = BT_PACKET_OWNER_STACK;
    (*packet)->packet_end  = (*packet)->packet_start + header_size + data_size;
    (*packet)->data_start  = (*packet)->packet_start + header_size;
    (*packet)->data_end    = (*packet)->data_start;
    bt_dynamic_packet_created++;

    return WICED_BT_SUCCESS;
}
Beispiel #3
0
/**
 *  Application Define function - creates and starts the application thread
 *  Called by ThreadX whilst it is initialising
 *
 *  @param first_unused_memory: unused parameter - required to match prototype
 */
void tx_application_define( void *first_unused_memory )
{
    TX_THREAD* app_thread_handle;
    char*      app_thread_stack;
    UINT       result;

    UNUSED_PARAMETER(first_unused_memory);

    /* Restore system clock taking into account time spent in deep-sleep */
    if ( WICED_DEEP_SLEEP_IS_WARMBOOT_HANDLE( ) )
    {
        tx_time_set( before_deep_sleep_time + wiced_deep_sleep_ticks_since_enter( ) );
    }

    /* Create the application thread.  */
    app_thread_handle = (TX_THREAD*)MALLOC_OBJECT("app thread", TX_THREAD);
    app_thread_stack  = (char*)malloc_named("app stack", APPLICATION_STACK_SIZE);

    result = tx_thread_create( app_thread_handle, (char*)"app thread", application_thread_main, 0, app_thread_stack, APPLICATION_STACK_SIZE, WICED_APPLICATION_PRIORITY, WICED_APPLICATION_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_START );

    if ( TX_SUCCESS != result )
    {
        free ( app_thread_handle );
        free ( app_thread_stack );
        app_thread_handle = NULL;
        app_thread_stack  = NULL;
    }
    else
    {
        ( void )tx_thread_entry_exit_notify( app_thread_handle, application_thread_cleanup );
    }
}
Beispiel #4
0
wiced_result_t wiced_rtos_init_queue( wiced_queue_t* queue, const char* name, uint32_t message_size, uint32_t number_of_messages )
{
    uint32_t queue_size = message_size * number_of_messages;
    wiced_result_t result;

    UNUSED_PARAMETER( name );

    if ( ( message_size % 4 ) > 0 )
    {
        return WICED_ERROR;
    }

    queue->buffer = (void*) malloc_named( "queue", queue_size );
    if ( queue->buffer == NULL )
    {
        return WICED_OUT_OF_HEAP_SPACE;
    }
    malloc_transfer_to_curr_thread( queue->buffer );

    result =  (wiced_result_t) host_rtos_init_queue( WICED_GET_QUEUE_HANDLE( queue ), queue->buffer, queue_size, message_size );

    if ( result != WICED_WWD_SUCCESS )
    {
        free( queue->buffer );
        queue->buffer = NULL;
    }

    return result;
}
Beispiel #5
0
/*-----------------------------------------------------------------------------------
 * Starts a new thread with priority "prio" that will begin its execution in the
 * function "thread()". The "arg" argument will be passed as an argument to the
 * thread() function. The id of the new thread is returned. Both the id and
 * the priority are system dependent.
 */
/*@null@*/ int  sys_thread_new( const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio, sys_thread_t* thread_out )
{
    emos_task_t* task = malloc_named("sys_thread_new", sizeof(emos_task_t));
    task->stack = malloc_named("sys_thread_new", stacksize*sizeof(int));


    /* The first time this is called we are creating the lwIP handler. */
    OS_CreateTaskEx(&task->task, name, prio, thread, task->stack, stacksize*sizeof(int), 0, arg);

#if LWIP_SYS_ARCH_TIMEOUTS
    /* For each task created, store the task handle (pid) in the timers array.
     * This scheme doesn't allow for threads to be deleted
     */
    timeout_list[next_thread++].pid = created_task;
#endif /* if LWIP_SYS_ARCH_TIMEOUTS */

    *thread_out = task;
    return 0;//( result == pdPASS )? 0 : -1;
    //return((sys_thread_t)task);
}
Beispiel #6
0
wiced_result_t bt_packet_pool_init( bt_packet_pool_t* pool, uint32_t packet_count, uint32_t header_size, uint32_t data_size )
{
    uint32_t       packet_size = header_size + data_size + sizeof(bt_packet_t) - 1;
    uint32_t       buffer_size = packet_count * packet_size;
    uint8_t*       packet_ptr  = NULL;
    void*          buffer      = NULL;
    wiced_result_t result;
    uint32_t       a;

    memset( pool, 0, sizeof( *pool ) );

    buffer = (void*)malloc_named( "bt_packet_pool", buffer_size );
    if ( buffer == NULL )
    {
        return WICED_BT_OUT_OF_HEAP_SPACE;
    }

    result = linked_list_init( &pool->pool_list );
    if ( result != WICED_BT_SUCCESS )
    {
        return result;
    }

    pool->pool_id          = PACKET_POOL_ID;
    pool->max_packet_count = packet_count;
    pool->header_size      = header_size;
    pool->data_size        = data_size;
    pool->pool_buffer      = buffer;
    packet_ptr             = buffer;

    for ( a = 0; a < packet_count; a++ )
    {
        bt_packet_t* packet = (bt_packet_t*)packet_ptr;

        result = linked_list_insert_node_at_front( &pool->pool_list, &packet->node );

        if ( result == WICED_BT_SUCCESS )
        {
            packet->node.data = (void*)packet;
            packet->pool      = pool;
            packet->packet_id = PACKET_ID;

        }
        else
        {
            return result;
        }

        packet_ptr += packet_size;
    }

    return wiced_rtos_init_mutex( &pool->mutex );
}
Beispiel #7
0
wiced_result_t wiced_easy_setup_start_cooee( wiced_easy_setup_cooee_callback_t callback )
{
    wiced_cooee_workspace_t* workspace = malloc_named( "cooee", sizeof(wiced_cooee_workspace_t) );
    if ( workspace == NULL )
    {
        return WICED_OUT_OF_HEAP_SPACE;
    }
    memset(workspace, 0, sizeof(wiced_cooee_workspace_t));
    wiced_wifi_cooee( workspace );

    callback( workspace->user_processed_data, (uint16_t) ( workspace->received_byte_count - ( workspace->user_processed_data - workspace->received_cooee_data ) ) );

    free( workspace );

    return WICED_SUCCESS;
}
Beispiel #8
0
wiced_result_t wiced_bt_smart_attribute_create( wiced_bt_smart_attribute_t** attribute, wiced_bt_smart_attribute_type_t type, uint16_t variable_length )
{
    uint16_t size;

    if ( attribute == NULL )
    {
        return WICED_BT_BADARG;
    }

    switch ( type )
    {
        case WICED_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE:
        {
            size = ATTR_CHARACTERISTIC_VALUE_SIZE( variable_length );
            break;
        }
        case WICED_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_USER_DESCRIPTION:
        {
            size = ATTR_USER_DESCRIPTION_SIZE( variable_length );
            break;
        }
        case WICED_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_AGGREGATE_FORMAT:
        {
            size = ATTR_AGGREGATE_FORMAT_SIZE( variable_length );
            break;
        }
        default:
        {
            size = fixed_attribute_size_list[type];
            break;
        }
    }

    *attribute = (wiced_bt_smart_attribute_t*)malloc_named("attribute", size );

    if ( *attribute == NULL )
    {
        return WICED_BT_OUT_OF_HEAP_SPACE;
    }

    memset( *attribute, 0, size );
    (*attribute)->value_struct_size = size - ATTR_COMMON_FIELDS_SIZE;
    attributes_created++;

    return WICED_BT_SUCCESS;
}
Beispiel #9
0
int read_wlan_chip_console_log(int argc, char *argv[])
{
	const unsigned buffer_size = 200;
	int result = -1;

	char *buffer = (char *)malloc_named("console", buffer_size);
	if (buffer == NULL) {
		return result;
	}

	if (wwd_wifi_read_wlan_log(buffer, buffer_size) == WWD_SUCCESS) {
		result = 0;
	}

	free(buffer);

	return result;
}
Beispiel #10
0
wiced_result_t gpio_keypad_enable( gpio_keypad_t* keypad, wiced_worker_thread_t* thread, gpio_keypad_handler_t function, uint32_t held_event_interval_ms, uint32_t total_keys, const gpio_key_t* key_list )
{
    gpio_key_internal_t* key_internal;
    uint32_t malloc_size;
    uint32_t i;

    if ( !keypad || !thread || !function || !total_keys || !key_list )
    {
        return WICED_BADARG;
    }

    malloc_size      = sizeof(gpio_keypad_internal_t) + total_keys * sizeof(gpio_key_internal_t);
    keypad->internal = (gpio_keypad_internal_t*) malloc_named("key internal", malloc_size);
    if ( !keypad->internal )
    {
        return WICED_ERROR;
    }

    memset( keypad->internal, 0, sizeof( *( keypad->internal ) ) );

    key_internal = (gpio_key_internal_t*)((uint8_t*)keypad->internal + sizeof(gpio_keypad_internal_t));

    keypad->internal->function   = function;
    keypad->internal->thread     = thread;
    keypad->internal->total_keys = total_keys;
    keypad->internal->key_list   = (gpio_key_t*)key_list;

    wiced_rtos_init_timer( &keypad->internal->check_state_timer, held_event_interval_ms, check_state_timer_handler, (void*) keypad->internal );

    for ( i = 0; i < total_keys; i++ )
    {
        wiced_gpio_irq_trigger_t trigger = ( key_list[i].polarity == KEY_POLARITY_HIGH ) ? IRQ_TRIGGER_FALLING_EDGE : IRQ_TRIGGER_RISING_EDGE;

        key_internal[i].key   = (gpio_key_t*)&key_list[i];
        key_internal[i].owner = keypad->internal;
        key_internal[i].last_irq_timestamp = 0;

        wiced_gpio_init( key_list[i].gpio, ( ( key_list[i].polarity == KEY_POLARITY_HIGH ) ? INPUT_PULL_UP : INPUT_PULL_DOWN ) );
        wiced_gpio_input_irq_enable( key_list[i].gpio, trigger, gpio_interrupt_key_handler, (void*)&key_internal[i] );
    }

    return WICED_SUCCESS;
}
Beispiel #11
0
wiced_result_t wiced_rtos_create_thread( wiced_thread_t* thread, uint8_t priority, const char* name, wiced_thread_function_t function, uint32_t stack_size, void* arg )
{
    wiced_result_t result;

    thread->stack = malloc_named( "stack", stack_size );
    if (thread->stack == NULL)
    {
        return WICED_OUT_OF_HEAP_SPACE;
    }
    malloc_transfer_to_curr_thread( thread->stack );

    result = (wiced_result_t) host_rtos_create_thread_with_arg( WICED_GET_THREAD_HANDLE( thread ), function, name, thread->stack, stack_size, priority, (uint32_t)arg );

    if ( result != WICED_WWD_SUCCESS )
    {
        free( thread->stack );
        thread->stack = NULL;
    }

    return result;
}
Beispiel #12
0
/*-----------------------------------------------------------------------------------
 * Creates and returns a new semaphore. The "count" argument specifies
 * the initial state of the semaphore. TBD finish and test
 */
err_t sys_sem_new( /*@special@*/ /*@out@*/ sys_sem_t *sem, u8_t count) /*@allocates *sem@*/
{
    if ( sem == NULL )
    {
        /*@-mustdefine@*/ /*@-compdef@*/ /* do not need to allocate or set *sem */
        return ERR_VAL;
        /*@+mustdefine@*/ /*@+compdef@*/
    }
    *sem = malloc_named("sys_sem_new", sizeof(OS_CSEMA));
// I am not sure but was protected in the orignal freertos code
    OS_EnterRegion();
    if ( count == (u8_t) 0 ) /* Means it can't be taken */
    {
        OS_CREATECSEMA(*sem);
    }
    else
    {
        OS_CreateCSema(*sem, count);
    }
    OS_LeaveRegion();
    /*@-compdef@*/ /* Lint doesnt realise allocation has occurred */
    return ERR_OK;
    /*@+compdef@*/
}
wiced_result_t bt_smartbridge_att_cache_enable( uint32_t cache_count )
{
    uint32_t a;
    wiced_result_t result;
    bt_smartbridge_att_cache_manager_t* manager;

    if ( att_cache_manager != NULL )
    {
        return WICED_BT_SUCCESS;
    }

    manager = (bt_smartbridge_att_cache_manager_t*)malloc_named( "att_cache", CALCULATE_ATT_CACHE_MANAGER_SIZE( cache_count ) );
    if ( manager == NULL )
    {
        return WICED_BT_OUT_OF_HEAP_SPACE;
    }

    memset( manager, 0, CALCULATE_ATT_CACHE_MANAGER_SIZE( cache_count ) );

    att_cache_manager = manager;
    manager->count    = cache_count;

    result = bt_linked_list_init( &manager->free_list );
    if ( result != WICED_BT_SUCCESS )
    {
        WPRINT_LIB_INFO( ( "Error creating linked list\n" ) );
        goto error;
    }

    result = bt_linked_list_init( &manager->used_list );
    if ( result != WICED_BT_SUCCESS )
    {
        WPRINT_LIB_INFO( ( "Error creating linked list\n" ) );
        goto error;
    }

    result = wiced_rtos_init_mutex( &manager->mutex );
    if ( result != WICED_SUCCESS )
    {
        WPRINT_LIB_INFO( ( "Error creating mutex\n" ) );
        goto error;
    }

    /* Initialise mutexes for protecting access to cached attributes */
    for ( a = 0; a < manager->count; a++ )
    {
        result = wiced_rtos_init_mutex( &manager->pool[a].mutex );
        if ( result != WICED_BT_SUCCESS )
        {
            goto error;
        }

        /* Point node data to cached attribute instance */
        manager->pool[a].node.data = (void*)&manager->pool[a];

        /* Insert cached attribute instance into free list */
        result = bt_linked_list_insert_at_rear( &manager->free_list, &manager->pool[a].node );
        if ( result != WICED_BT_SUCCESS )
        {
            goto error;
        }
    }

    return WICED_BT_SUCCESS;

    error:
    bt_smartbridge_att_cache_disable();
    return result;
}
static wiced_result_t smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t* cache, uint16_t connection_handle )
{
    /* This function performs the following:
     * 1. Primary Services discovery
     * 2. Relationship (Included Services) Discovery for every Primary Service
     * 3. Characteristic Discovery for every Primary Service
     * 4. Characteristic Value Read for every Charactertistic
     * 5. Characteristic Descriptor Discovery for every Characteristic
     */

    wiced_bt_smart_attribute_t**     primary_service_array    = NULL;
    wiced_bt_smart_attribute_t**     characteristic_array     = NULL;
    wiced_bt_smart_attribute_t*      characteristic_value     = NULL;
    wiced_bt_smart_attribute_t*      descriptor_with_no_value = NULL;
    wiced_bt_smart_attribute_t*      descriptor_with_value    = NULL;
    wiced_bt_smart_attribute_t*      iterator                 = NULL;
    wiced_result_t                   result                   = WICED_SUCCESS;
    wiced_result_t                   error_code_var           = WICED_ERROR;
    uint32_t                         i                        = 0;
    uint32_t                         j                        = 0;
    uint32_t                         primary_service_count    = 0;
    uint32_t                         characteristic_count     = 0;
    wiced_bt_smart_attribute_list_t  primary_service_list;
    wiced_bt_smart_attribute_list_t  included_service_list;
    wiced_bt_smart_attribute_list_t  characteristic_list;
    wiced_bt_smart_attribute_list_t  descriptor_list;

    if ( att_cache_manager == NULL )
    {
        return WICED_BT_ATT_CACHE_UNINITIALISED;
    }

    /* Initialise local variables */
    memset( &primary_service_list,  0, sizeof( primary_service_list  ) );
    memset( &included_service_list, 0, sizeof( included_service_list ) );
    memset( &characteristic_list,   0, sizeof( characteristic_list   ) );
    memset( &descriptor_list,       0, sizeof( descriptor_list       ) );

    wiced_rtos_lock_mutex( &cache->mutex );

    result = wiced_bt_smart_attribute_create_list( &primary_service_list );

    wiced_rtos_unlock_mutex( &cache->mutex );

    CHECK_FOR_ERROR( result != WICED_BT_SUCCESS, result );

    /**************************************************************************
     * Primary Services Discovery
     **************************************************************************/
    result = bt_smart_gatt_discover_all_primary_services( connection_handle, &primary_service_list );

    CHECK_FOR_ERROR( result != WICED_BT_SUCCESS, result );

    wiced_bt_smart_attribute_get_list_count( &primary_service_list, &primary_service_count );

    primary_service_array = (wiced_bt_smart_attribute_t**)malloc_named( "svc_array", primary_service_count * sizeof(wiced_bt_smart_attribute_t));

    CHECK_FOR_ERROR( primary_service_array == NULL, WICED_BT_OUT_OF_HEAP_SPACE );

    /* Keep the original pointers to the primary service list before the list gets merged */
    wiced_bt_smart_attribute_get_list_head( &primary_service_list, &iterator );

    for ( i = 0; i < primary_service_count; i++ )
    {
        primary_service_array[i] = iterator;
        iterator                 = iterator->next;
    }

    /* Check if characteristic is readable. If not readable, create a control-point attribute */
    for ( i = 0; i < primary_service_count; i++ )
    {
        /* Initialise variable for this iteration */
        memset( &characteristic_list,   0, sizeof( characteristic_list   ) );
        memset( &included_service_list, 0, sizeof( included_service_list ) );
        characteristic_array = NULL;

        /**********************************************************************
         * Relationship Discovery
         **********************************************************************/
        result = bt_smart_gatt_find_included_services( connection_handle, primary_service_array[i]->value.service.start_handle, primary_service_array[i]->value.service.start_handle, &included_service_list );

        CHECK_FOR_ERROR( result == WICED_BT_GATT_TIMEOUT, result );

        wiced_rtos_lock_mutex( &cache->mutex );

        result = wiced_bt_smart_attribute_merge_lists( &primary_service_list, &included_service_list );

        wiced_rtos_unlock_mutex( &cache->mutex );

        CHECK_FOR_ERROR( result != WICED_BT_SUCCESS, result );

        /**********************************************************************
         * Characteristic Discovery
         **********************************************************************/
        result = bt_smart_gatt_discover_all_characteristics_in_a_service( connection_handle, primary_service_array[i]->value.service.start_handle, primary_service_array[i]->value.service.end_handle, &characteristic_list );

        CHECK_FOR_ERROR( result == WICED_BT_GATT_TIMEOUT, result );

        wiced_bt_smart_attribute_get_list_count( &characteristic_list, &characteristic_count );

        characteristic_array = (wiced_bt_smart_attribute_t**)malloc_named( "char_array", characteristic_count * sizeof(characteristic_list));

        CHECK_FOR_ERROR( characteristic_array == NULL, WICED_BT_OUT_OF_HEAP_SPACE );

        /* Keep the original pointers to the characteristic list before the list gets merged. */
        wiced_bt_smart_attribute_get_list_head( &characteristic_list, &iterator );

        for ( j = 0; j < characteristic_count; j++ )
        {
            characteristic_array[j] = iterator;
            iterator                = iterator->next;
        }

        /* Traverse through all characteristics to perform Characteristic Value Read and Descriptors Discovery */
        for ( j = 0; j < characteristic_count; j++ )
        {
            /* Initialise local variables for this iteration */
            memset( &descriptor_list, 0, sizeof( descriptor_list ) );
            characteristic_value = NULL;

            /******************************************************************
             * Characteristic Value Read
             ******************************************************************/
            if ( ( characteristic_array[j]->value.characteristic.properties & 0x02 ) != 0 )
            {
                /* If characteristic is readable. If not readable, create a control-point attribute */
                result = bt_smart_gatt_read_characteristic_value( connection_handle, characteristic_array[j]->value.characteristic.value_handle, &characteristic_array[j]->value.characteristic.uuid, &characteristic_value );

                CHECK_FOR_ERROR( result == WICED_BT_GATT_TIMEOUT, result );
            }
            else
            {
                /* Failed to read. Let's enter a control-point attribute (dummy) here so when notification come, UUID is known. */
                result = wiced_bt_smart_attribute_create( &characteristic_value, WICED_ATTRIBUTE_TYPE_NO_VALUE, 0 );

                if ( result == WICED_BT_SUCCESS )
                {
                    characteristic_value->handle = characteristic_array[j]->value.characteristic.value_handle;
                    characteristic_value->type   = characteristic_array[j]->value.characteristic.uuid;
                }

                CHECK_FOR_ERROR( result != WICED_BT_SUCCESS, result );
            }

            if ( characteristic_value != NULL )
            {
                /* Add Characteristic Value to main list */
                wiced_rtos_lock_mutex( &cache->mutex );

                result = wiced_bt_smart_attribute_add_to_list( &primary_service_list, characteristic_value );

                wiced_rtos_unlock_mutex( &cache->mutex );

                CHECK_FOR_ERROR( result != WICED_BT_SUCCESS, result );
            }

            /******************************************************************
             * Characteristic Descriptor Discovery
             ******************************************************************/
            if ( characteristic_array[j]->value.characteristic.descriptor_start_handle <= characteristic_array[j]->value.characteristic.descriptor_end_handle )
            {
                result = bt_smart_gatt_discover_all_characteristic_descriptors( connection_handle, characteristic_array[j]->value.characteristic.descriptor_start_handle, characteristic_array[j]->value.characteristic.descriptor_end_handle, &descriptor_list );

                CHECK_FOR_ERROR( result == WICED_BT_GATT_TIMEOUT, result );

                wiced_bt_smart_attribute_get_list_head( &descriptor_list, &descriptor_with_no_value );

                /* Traverse through all descriptors */
                while ( descriptor_with_no_value != NULL )
                {
                    /* Initialise variable for this iteration */
                    descriptor_with_value = NULL;

                    result = bt_smart_gatt_read_characteristic_descriptor( connection_handle, descriptor_with_no_value->handle, &descriptor_with_no_value->type, &descriptor_with_value );

                    CHECK_FOR_ERROR( result == WICED_BT_GATT_TIMEOUT, result );

                    /* Add Descriptor with Value to main list */
                    result = wiced_bt_smart_attribute_add_to_list( &primary_service_list, descriptor_with_value );

                    CHECK_FOR_ERROR( result != WICED_BT_SUCCESS, result );

                    descriptor_with_no_value = descriptor_with_no_value->next;
                }

                /* Delete the empty descriptor list */
                result = wiced_bt_smart_attribute_delete_list( &descriptor_list );

                CHECK_FOR_ERROR( result != WICED_BT_SUCCESS, result );
            }
        }

        /* Merge Characteristics to main list */
        wiced_rtos_lock_mutex( &cache->mutex );

        result = wiced_bt_smart_attribute_merge_lists( &primary_service_list, &characteristic_list );

        wiced_rtos_unlock_mutex( &cache->mutex );

        CHECK_FOR_ERROR( result != WICED_BT_SUCCESS, result );

        /* Free primary service array */
        free( characteristic_array );
    }

    /* Free primary service array */
    free( primary_service_array );

    /* Successful. Now copy the primary service list to the cached attributes list */
    memcpy( &cache->attribute_list, &primary_service_list, sizeof( cache->attribute_list ) );

    return WICED_BT_SUCCESS;

    error:


    /* Delete all local attributes */
    if ( iterator != NULL )
    {
        wiced_bt_smart_attribute_delete( iterator );
    }

    if ( descriptor_with_no_value != NULL )
    {
        wiced_bt_smart_attribute_delete( descriptor_with_no_value );
    }

    if ( descriptor_with_value != NULL )
    {
        wiced_bt_smart_attribute_delete( descriptor_with_value );
    }

    if ( characteristic_value != NULL )
    {
        wiced_bt_smart_attribute_delete( characteristic_value );
    }

    if ( characteristic_array != NULL )
    {
        free( characteristic_array );
    }

    if ( primary_service_array != NULL )
    {
        free( primary_service_array );
    }

    wiced_bt_smart_attribute_delete_list( &descriptor_list );
    wiced_bt_smart_attribute_delete_list( &characteristic_list );
    wiced_bt_smart_attribute_delete_list( &included_service_list );
    wiced_bt_smart_attribute_delete_list( &primary_service_list );

    /* Return the error code to the caller */
    return error_code_var;
}
bool AdafruitTwitter::checkDirectMessage(uint64_t since_id, uint64_t max_id)
{
  // False if setDirectMessageRecvCallback() is not called
  VERIFY(_dm_rx_callback);

#if TWITTER_DEBUG // test code
  since_id = 240136858829479935ULL;
#endif

//  char const count_str[] = { '0' + count , 0};
  char sinceid_str[64];
  sprintf(sinceid_str, "%llu", since_id);

  char maxid_str[64];
  sprintf(maxid_str, "%llu", max_id);

  // Data contents: ASSUME key are already in urlencoded
  char const* httpdata[][2] =
  {
      { "count"    , "1"         },
      { "since_id" , sinceid_str },
      { "max_id "  , maxid_str   },
  };
  uint8_t data_count = arrcount(httpdata);

  if ( max_id == 0 ) data_count--;

  // Send HTTP request
  AdafruitHTTP http;
  send_http_request(http, HTTP_METHOD_GET, TWITTER_JSON_DIRECTMESSAGE, httpdata, data_count);

  // Process HTTP response
  TwitterDM dm;

  http.respParseHeader();

  // Content Length is too short for a new message --> skip
  // Only process response if message is arrived
  if ( http.respContentLength() > 100 )
  {
    char buffer[256];
    while ( http.readUntil(',', buffer, sizeof(buffer)) )
    {
      char* key = buffer;
      char* value = strchr(buffer, ':');

      if ( value == NULL ) continue;
      *value++ = 0; // separate key & value with null-terminator

      // Both interested (key and value) are quoted, discard them
      key++;
      key[strlen(key)-1] = 0;

      value++;
      value[strlen(value)-1] = 0;

      //    Serial.print(key); Serial.print('='); Serial.println(value);

      if ( (dm.id == 0) && !strcmp("id_str", key) )
      {
        dm.id = strtoull(value, NULL, 10);
      }

      if ( (dm.text == NULL) && !strcmp("text", key) )
      {
        dm.text = (char*) malloc_named("Twitter DM", strlen(value) + 1);
        VERIFY(dm.text != NULL);

        strcpy(dm.text, value);
      }

      if ( (dm.sender == NULL) && !strcmp("screen_name", key) )
      {
        dm.sender = (char*) malloc_named("Twitter DM", strlen(value) + 1);
        VERIFY( dm.sender != NULL );

        strcpy(dm.sender, value);
      }

      if ( !strcmp("created_at", key) )
      {
        // message time is likely the last time field
        if ( dm.created_at == NULL )
        {
          dm.created_at = (char*) malloc_named("Twitter DM", strlen(value) + 10);
          VERIFY( dm.created_at != NULL );
        }

        strcpy(dm.created_at, value);
      }
    }
  }

  http.stop();

  // There is new message
  if (dm.id)
  {
    // update last sinceid
    _dm_last_sinceid = dm.id;

    // Fire callback
    _dm_rx_callback(dm);

    // clean up DM resource
    if (dm.sender     ) free_named("Twitter DM", dm.sender);
    if (dm.text       ) free_named("Twitter DM", dm.text);
    if (dm.created_at ) free_named("Twitter DM", dm.created_at);
  }

  return true;
}
Beispiel #16
0
void* tls_host_malloc( const char* name, uint32_t size)
{
    (void) name;
    return malloc_named( name, size );
}
static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t* cache, uint16_t connection_handle )
{
    /* This function performs the following:
     * 1. Primary Services discovery
     * 2. Relationship (Included Services) Discovery for every Primary Service
     * 3. Characteristic Discovery for every Primary Service
     * 4. Characteristic Value Read for every Charactertistic
     * 5. Characteristic Descriptor Discovery for every Characteristic
     */

    mico_bt_smart_attribute_t**     primary_service_array    = NULL;
    mico_bt_smart_attribute_t**     characteristic_array     = NULL;
    mico_bt_smart_attribute_t*      characteristic_value     = NULL;
    mico_bt_smart_attribute_t*      descriptor_with_no_value = NULL;
    mico_bt_smart_attribute_t*      descriptor_with_value    = NULL;
    mico_bt_smart_attribute_t*      iterator                 = NULL;
    OSStatus                         result                   = MICO_BT_SUCCESS;
    OSStatus                         error_code_var           = MICO_BT_ERROR;
    uint32_t                         i                        = 0;
    uint32_t                         j                        = 0;
    uint32_t                         primary_service_count    = 0;
    uint32_t                         characteristic_count     = 0;
    mico_bt_smart_attribute_list_t  primary_service_list;
    mico_bt_smart_attribute_list_t  branch_primary_service_list;
    mico_bt_smart_attribute_list_t  included_service_list;
    mico_bt_smart_attribute_list_t  characteristic_list;
    mico_bt_smart_attribute_list_t  descriptor_list;

    mico_bool_t characteristic_list_merged = MICO_FALSE;
    mico_bool_t included_service_list_merged = MICO_FALSE;

    if ( att_cache_manager == NULL )
    {
        return MICO_BT_ATT_CACHE_UNINITIALISED;
    }

    /* Initialise local variables */
    memset( &primary_service_list,          0, sizeof( primary_service_list  ) );
    memset( &branch_primary_service_list,   0, sizeof( primary_service_list  ) );
    memset( &included_service_list,         0, sizeof( included_service_list ) );
    memset( &characteristic_list,           0, sizeof( characteristic_list   ) );
    memset( &descriptor_list,               0, sizeof( descriptor_list       ) );

    mico_rtos_lock_mutex( &cache->mutex );

    result = mico_bt_smart_attribute_create_list( &primary_service_list );

    mico_rtos_unlock_mutex( &cache->mutex );

    CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );

    /**************************************************************************
     * Primary Services Discovery
     **************************************************************************/
    if( att_cache_manager->att_cache_services_count == 0 )
    {
        result = smartbridge_bt_interface_discover_all_primary_services( connection_handle, &primary_service_list );
        CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
    }
    else
    {
        for ( i = 0; i < att_cache_manager->att_cache_services_count; i++ )
        {
            result = smartbridge_bt_interface_discover_primary_services_by_uuid( connection_handle, &att_cache_manager->att_cache_services[i], &branch_primary_service_list );
            CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
            result = mico_bt_smart_attribute_merge_lists( &primary_service_list, &branch_primary_service_list );
            CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
        }
    }

    mico_bt_smart_attribute_get_list_count( &primary_service_list, &primary_service_count );

    primary_service_array = (mico_bt_smart_attribute_t**)malloc_named( "svc_array", primary_service_count * sizeof(mico_bt_smart_attribute_t));

    CHECK_FOR_ERROR( primary_service_array == NULL, MICO_BT_OUT_OF_HEAP_SPACE );

    /* Keep the original pointers to the primary service list before the list gets merged */
    mico_bt_smart_attribute_get_list_head( &primary_service_list, &iterator );

    for ( i = 0; i < primary_service_count; i++ )
    {
        primary_service_array[i] = iterator;
        iterator                 = iterator->next;
    }

    bt_smartbridge_log( "[Cache] All services discovered. count: %u",(unsigned int) primary_service_count );

    /* Check if characteristic is readable. If not readable, create a control-point attribute */
    for ( i = 0; i < primary_service_count; i++ )
    {
        /* Initialise variable for this iteration */
        memset( &characteristic_list,   0, sizeof( characteristic_list   ) );
        memset( &included_service_list, 0, sizeof( included_service_list ) );
        characteristic_array = NULL;

        /**********************************************************************
         * Relationship Discovery
         **********************************************************************/
        /*result = bt_smart_gatt_find_included_services( connection_handle, primary_service_array[i]->value.service.start_handle, primary_service_array[i]->value.service.start_handle, &included_service_list );

        CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT, result );

        mico_rtos_lock_mutex( &cache->mutex );

        result = mico_bt_smart_attribute_merge_lists( &primary_service_list, &included_service_list );

        if( result == MICO_BT_SUCCES )
        {
            included_service_list_merged = MICO_TRUE;
        }

        mico_rtos_unlock_mutex( &cache->mutex );

        CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
        */

        /**********************************************************************
         * Characteristic Discovery
         **********************************************************************/
        result = smartbridge_bt_interface_discover_all_characteristics_in_a_service( connection_handle, primary_service_array[i]->value.service.start_handle, primary_service_array[i]->value.service.end_handle, &characteristic_list );

        CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT || result == MICO_BT_TIMEOUT, result );

        mico_bt_smart_attribute_get_list_count( &characteristic_list, &characteristic_count );


        characteristic_array = (mico_bt_smart_attribute_t**)malloc_named( "char_array", characteristic_count * sizeof(characteristic_list));

        CHECK_FOR_ERROR( characteristic_array == NULL, MICO_BT_OUT_OF_HEAP_SPACE );

        /* Keep the original pointers to the characteristic list before the list gets merged. */
        mico_bt_smart_attribute_get_list_head( &characteristic_list, &iterator );

        for ( j = 0; j < characteristic_count; j++ )
        {
            characteristic_array[j] = iterator;
            iterator                = iterator->next;
        }

        /* Traverse through all characteristics to perform Characteristic Value Read and Descriptors Discovery */
        for ( j = 0; j < characteristic_count; j++ )
        {
            /* Initialise local variables for this iteration */
            memset( &descriptor_list, 0, sizeof( descriptor_list ) );
            characteristic_value = NULL;

            /******************************************************************
             * Characteristic Value Read
             ******************************************************************/
            if ( ( characteristic_array[j]->value.characteristic.properties & 0x02 ) != 0 )
            {
                bt_smartbridge_log( "[Cache] Characteristic Read-Property IS set" );
                /* If characteristic is readable. If not readable, create a control-point attribute */
                result = smartbridge_bt_interface_read_characteristic_value( connection_handle, characteristic_array[j]->value.characteristic.value_handle, &characteristic_array[j]->value.characteristic.uuid, &characteristic_value );

                CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT || result == MICO_BT_TIMEOUT, result );
            }
            else
            {
                bt_smartbridge_log( "[Cache] Characteristic Read-Properties is NOT set" );
                /* Failed to read. Let's enter a control-point attribute (dummy) here so when notification come, UUID is known. */
                result = mico_bt_smart_attribute_create( &characteristic_value, MICO_ATTRIBUTE_TYPE_NO_VALUE, 0 );

                if ( result == MICO_BT_SUCCESS )
                {
                    characteristic_value->handle = characteristic_array[j]->value.characteristic.value_handle;
                    characteristic_value->type   = characteristic_array[j]->value.characteristic.uuid;
                }

                CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
            }

            if ( characteristic_value != NULL )
            {
                /* Add Characteristic Value to main list */
                mico_rtos_lock_mutex( &cache->mutex );

                /* Add characteristic_value to main list */
                result = mico_bt_smart_attribute_add_to_list( &primary_service_list, characteristic_value );

                /* Merge success, it will be deleted by primary_service_list when error */
                if( result == MICO_BT_SUCCESS )
                {
                    characteristic_value = NULL;
                }

                mico_rtos_unlock_mutex( &cache->mutex );

                CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
            }
            /******************************************************************
             * Characteristic Descriptor Discovery
             ******************************************************************/
             
            /* If descriptor_start_handle is equal to the next characteristic's handle, stop, add by william  */
            if( (j < (characteristic_count - 1)) && (characteristic_array[j]->value.characteristic.descriptor_end_handle >= characteristic_array[j+1]->handle) )
                continue;

            /* If descriptor_start_handle is equal to the next service handle, stop, add by william  */
            if( (j == (characteristic_count - 1)) && (i < (primary_service_count - 1))&& (characteristic_array[j]->value.characteristic.descriptor_end_handle >= primary_service_array[i+1]->handle) )
                continue;


            if ( characteristic_array[j]->value.characteristic.descriptor_start_handle <= characteristic_array[j]->value.characteristic.descriptor_end_handle )
            {
                result = smartbridge_bt_interface_discover_all_characteristic_descriptors( connection_handle, characteristic_array[j]->value.characteristic.descriptor_start_handle, characteristic_array[j]->value.characteristic.descriptor_end_handle, &descriptor_list );

                CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT || result == MICO_BT_TIMEOUT, result );

                mico_bt_smart_attribute_get_list_head( &descriptor_list, &descriptor_with_no_value );

                /* Traverse through all descriptors */
                while ( descriptor_with_no_value != NULL )
                {
                    /* Initialise variable for this iteration */
                    descriptor_with_value = NULL;

                    result = smartbridge_bt_interface_read_characteristic_descriptor( connection_handle, descriptor_with_no_value->handle, &descriptor_with_no_value->type, &descriptor_with_value );

                    CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT || result == MICO_BT_TIMEOUT, result );

                    /* Add Descriptor with Value to main list */
                    result = mico_bt_smart_attribute_add_to_list( &primary_service_list, descriptor_with_value );

                    /* Merge success, it will be deleted by primary_service_list when error */
                    if( result == MICO_BT_SUCCESS )
                    {
                        descriptor_with_value = NULL;
                    }

                    CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );

                    descriptor_with_no_value = descriptor_with_no_value->next;
                }

                /* Delete the empty descriptor list */
                result = mico_bt_smart_attribute_delete_list( &descriptor_list );

                CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );
            }
        }

        /* Merge Characteristics to main list */
        mico_rtos_lock_mutex( &cache->mutex );

        result = mico_bt_smart_attribute_merge_lists( &primary_service_list, &characteristic_list );

        if( result == MICO_BT_SUCCESS )
        {
            characteristic_list_merged = MICO_TRUE;
        }

        mico_rtos_unlock_mutex( &cache->mutex );

        CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result );

        /* Free primary service array */
        free( characteristic_array );
    }

    /* Free primary service array */
    free( primary_service_array );

    /* Successful. Now copy the primary service list to the cached attributes list */
    memcpy( &cache->attribute_list, &primary_service_list, sizeof( cache->attribute_list ) );

    //mico_bt_smart_attribute_print_list( &(cache->attribute_list) );

    return MICO_BT_SUCCESS;

    error:


    /* Delete all local attributes */

    if ( descriptor_with_value != NULL )
    {
        mico_bt_smart_attribute_delete( descriptor_with_value );
    }

    if ( characteristic_value != NULL )
    {
        mico_bt_smart_attribute_delete( characteristic_value );
    }

    if ( characteristic_array != NULL )
    {
        free( characteristic_array );
    }

    if ( primary_service_array != NULL )
    {
        free( primary_service_array );
    }

    if( characteristic_list_merged == MICO_FALSE )
    {
        mico_bt_smart_attribute_delete_list( &characteristic_list );
    }

    if( included_service_list_merged == MICO_FALSE )
    {
        mico_bt_smart_attribute_delete_list( &included_service_list );
    }

    mico_bt_smart_attribute_delete_list( &descriptor_list );
    mico_bt_smart_attribute_delete_list( &primary_service_list );

    /* Return the error code to the caller */
    return error_code_var;
}
Beispiel #18
0
void* tls_host_get_defragmentation_buffer ( uint16_t size )
{
    return malloc_named( "tls", size );
}
OSStatus bt_smartbridge_att_cache_enable( uint32_t cache_count, mico_bt_uuid_t cache_services[], uint32_t service_count )
{
    uint32_t a;
    OSStatus result;
    bt_smartbridge_att_cache_manager_t* manager;
    mico_bt_uuid_t* services = NULL;

    if ( att_cache_manager != NULL )
    {
        return MICO_BT_SUCCESS;
    }

    manager = (bt_smartbridge_att_cache_manager_t*)malloc_named( "att_cache", CALCULATE_ATT_CACHE_MANAGER_SIZE( cache_count ) );
    if ( manager == NULL )
    {
        return MICO_BT_OUT_OF_HEAP_SPACE;
    }

    if( service_count != 0 )
    {
        services = (mico_bt_uuid_t *)malloc_named( "cache_services", service_count * sizeof(mico_bt_uuid_t) );
        if ( services == NULL )
        {
            return MICO_BT_OUT_OF_HEAP_SPACE;
        }
    }


    memset( manager, 0, CALCULATE_ATT_CACHE_MANAGER_SIZE( cache_count ) );

    att_cache_manager = manager;
    manager->count    = cache_count;
    manager->att_cache_services_count = service_count;
    if( service_count != 0 )
    {
        manager->att_cache_services = services;
        memcpy( manager->att_cache_services, cache_services, service_count * sizeof(mico_bt_uuid_t) );        
    }


    result = linked_list_init( &manager->free_list );
    if ( result != MICO_BT_SUCCESS )
    {
        bt_smartbridge_log( "Error creating linked list\n" );
        goto error;
    }

    result = linked_list_init( &manager->used_list );
    if ( result != MICO_BT_SUCCESS )
    {
        bt_smartbridge_log( "Error creating linked list\n" );
        goto error;
    }

    result = mico_rtos_init_mutex( &manager->mutex );
    if ( result != MICO_BT_SUCCESS )
    {
        bt_smartbridge_log( "Error creating mutex\n" );
        goto error;
    }

    /* Initialise mutexes for protecting access to cached attributes */
    for ( a = 0; a < manager->count; a++ )
    {
        result = mico_rtos_init_mutex( &manager->pool[a].mutex );
        if ( result != MICO_BT_SUCCESS )
        {
            goto error;
        }

        /* Point node data to cached attribute instance */
        manager->pool[a].node.data = (void*)&manager->pool[a];

        /* Insert cached attribute instance into free list */
        result = linked_list_insert_node_at_rear( &manager->free_list, &manager->pool[a].node );
        if ( result != MICO_BT_SUCCESS )
        {
            goto error;
        }
    }

    return MICO_BT_SUCCESS;

    error:
    bt_smartbridge_att_cache_disable();
    return result;
}