/*----------------------------------------------------------------------------------- * 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@*/ }
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; }
/** * 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 ); } }
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; }
/*----------------------------------------------------------------------------------- * 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); }
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 ); }
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; }
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; }
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; }
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; }
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; }
/*----------------------------------------------------------------------------------- * 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; }
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; }
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; }