static struct tcp_pcb *connect(struct ip_addr *ip, int port) { // debug_printf("connect()\n"); err_t err; struct tcp_pcb *pcb; pcb = tcp_new(); if (pcb == NULL) { fprintf(stderr, "failed to create new pcb\n"); assert(pcb != NULL); return NULL; } // debug_printf("pcb created\n"); // debug_printf("connecting to server\n"); wait_cond = true; err = tcp_connect(pcb, ip, port, tcp_is_connected); wait_for_condition(); // TODO: proper error handling if (err != ERR_OK) { fprintf(stderr, "error connecting %d\n", err); return NULL; } return pcb; }
BleStatus ble_client_init(ble_client_gap_event_cb_t gap_event_cb, void *gap_event_param, ble_client_gatts_event_cb_t gatts_event_cb, void *gatts_event_param) { BleStatus status; uint32_t delay_until; cfw_platform_nordic_init(); client_handle = cfw_init(cfw_get_service_queue(), ble_core_client_handle_message, NULL); sync.response = 0; if (cfw_register_svc_available(client_handle, BLE_CORE_SERVICE_ID, NULL)) return BLE_STATUS_ERROR; /* Wait for response messages */ wait_for_condition(sync.response, status); if (status != BLE_STATUS_SUCCESS) return status; /* We need to wait for ~1 ms before continuing */ delay_until = get_uptime_32k() + TIMEOUT_TICKS_1MS; while (get_uptime_32k() < delay_until); sync.response = 0; cfw_open_service(client_handle, BLE_CORE_SERVICE_ID, NULL); /* Wait for response messages */ wait_for_condition(sync.response, status); if (status != BLE_STATUS_SUCCESS) return status; ble_client_gap_event_cb = gap_event_cb; ble_client_gap_event_param = gap_event_param; ble_client_gatts_event_cb = gatts_event_cb; ble_client_gatts_event_param = gatts_event_param; return sync.status; }
// FIX: make this non-recursive static errval_t send_message(struct tcp_pcb *pcb, void *msg, size_t len) { err_t err; // debug_printf("send_message(pcb: %p, msg: %p, len: %d)\n", // pcb, msg, (int)len); if (len > 0) { wait_cond = true; uint16_t send_size = MIN(tcp_sndbuf(pcb), len); // debug_printf("\tsend_size: %d.\n", send_size); if (send_size <= 0) { // debug_printf("\tnot enough space in sndbuf. will retry later.\n"); // ran out of memory, wait for a send to happen // debug_printf("\twaiting for condition.\n"); wait_for_condition(); // and try again // debug_printf("\tand trying again.\n"); send_message(pcb, msg, len); } else { // debug_printf("\tsent %d bytes of %lu.\n", send_size, len); err = tcp_write(pcb, msg, send_size, TCP_WRITE_FLAG_COPY); // TODO: proper error handling if (err != ERR_OK) { fprintf(stderr, "error writing %d\n", err); return LWIP_ERR_MEM; //TODO: what errno to use? } if (send_size < len) { // debug_printf("\tdidn't send whole message, so going to send rest now\n"); send_message(pcb, msg + send_size, len - send_size); } } } err = tcp_output(pcb); // TODO: proper error handling if (err != ERR_OK) { fprintf(stderr, "error in tcp_output %d\n", err); return LWIP_ERR_MEM; //TODO: what errno to use? } // debug_printf("done send_message()\n"); return SYS_ERR_OK; }
static errval_t do_send_file(struct in_addr *addr, int port, char *path) { assert(addr != NULL); assert(path != NULL); errval_t err; debug_printf("send file %s to %s:%d\n", path, inet_ntoa(*addr), port); static struct ip_addr ip; ip.addr = addr->s_addr; // XXX // debug_printf("ready to connect\n"); struct tcp_pcb *pcb; pcb = connect(&ip, port); if (pcb == NULL) { assert(pcb != NULL); // return SOME_ERR; } // debug_printf("connected\n"); // debug_printf("start sending.\n"); wait_cond = true; err = send_file(pcb, path); if (err_is_fail(err)) { return err; } wait_for_condition(); debug_printf("send finished.\n"); // debug_printf("closing connection.\n"); // close_connection(pcb); debug_printf("connection closed.\n"); return SYS_ERR_OK; }
BleStatus ble_client_gap_wr_adv_data(uint8_t *adv_data, const uint8_t adv_data_len) { BleStatus status; struct ble_gap_adv_rsp_data adv_rsp_data = { .p_data = adv_data, .len = adv_data_len, }; /* write advertisement data */ sync.response = 0; if (ble_gap_wr_adv_data(service_handle, &adv_rsp_data, NULL, NULL)) return BLE_STATUS_ERROR; /* Wait for response messages */ wait_for_condition(sync.response, status); if (status != BLE_STATUS_SUCCESS) return status; return sync.status; }
BleStatus ble_client_gap_set_enable_config(const char *name, const ble_addr_t *bda, const uint16_t appearance, const int8_t tx_power) { struct ble_wr_config config; BleStatus status; config.p_bda = (bda && bda->type != BLE_DEVICE_ADDR_INVALID) ? (ble_addr_t *)bda : NULL; config.p_name = (uint8_t *)name; config.appearance = appearance; config.tx_power = tx_power; config.peripheral_conn_params.interval_min = MIN_CONN_INTERVAL; config.peripheral_conn_params.interval_max = MAX_CONN_INTERVAL; config.peripheral_conn_params.slave_latency = SLAVE_LATENCY; config.peripheral_conn_params.link_sup_to = CONN_SUP_TIMEOUT; config.central_conn_params.interval_min = MIN_CONN_INTERVAL; config.central_conn_params.interval_max = MAX_CONN_INTERVAL; config.central_conn_params.slave_latency = SLAVE_LATENCY; config.central_conn_params.link_sup_to = CONN_SUP_TIMEOUT; sync.response = 0; if (ble_gap_set_enable_config(service_handle, &config, NULL)) return BLE_STATUS_ERROR; /* Wait for response message */ wait_for_condition(sync.response, status); if (status != BLE_STATUS_SUCCESS) return status; if (sync.status) return sync.status; struct ble_gap_sm_config_params sm_params = { .options = BLE_GAP_BONDING, .io_caps = BLE_GAP_IO_NO_INPUT_NO_OUTPUT, .key_size = 16, }; sync.response = 0; if (ble_gap_sm_config(service_handle, &sm_params, NULL)) return BLE_STATUS_ERROR; /* Wait for response message */ wait_for_condition(sync.response, status); if (status != BLE_STATUS_SUCCESS) return status; return sync.status; } BleStatus ble_client_gap_get_bda(ble_addr_t *p_bda) { BleStatus status; sync.response = 0; sync.param = (void *)p_bda; if (ble_gap_read_bda(service_handle, NULL)) return BLE_STATUS_ERROR; /* Wait for response message */ wait_for_condition(sync.response, status); if (status != BLE_STATUS_SUCCESS) return status; return sync.status; }
static void net_proxy_connected_cb(struct bulk_net_proxy *proxy) { errval_t err; struct block_net_service *c = (struct block_net_service *) proxy->user_state; c->bound++; BS_NET_DEBUG_BULK(" > Channel Connected. #conn=%i", c->bound); if (c->bound != 2) { return; } BS_NET_DEBUG_BULK("%s", "all channels connected. allocating pools\n"); err = bulk_alloc_init(&allocator_tx, BULK_NET_PROXY_NUMBUFS, BULK_NET_PROXY_BUFSIZE, NULL); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Failed to allocate pool\n"); } err = bulk_alloc_init(&allocator_rx, BULK_NET_PROXY_NUMBUFS, BULK_NET_PROXY_BUFSIZE, NULL); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Failed to allocate pool"); } struct bulk_continuation cont = { .handler = pool_assigned_cb, .arg = NULL, }; BS_NET_DEBUG_BULK("%s", " > Assigning pools to channels"); err = bulk_channel_assign_pool(&c->rx_chan, allocator_rx.pool, cont); if (err_is_fail(err)) { USER_PANIC_ERR(err, "failed to assign pool to channel"); } err = bulk_channel_assign_pool(&c->tx_chan, allocator_tx.pool, cont); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Failed to assign pool to channel"); } wait_cond = 1; wait_for_condition(); BS_NET_DEBUG_BULK("%s", "Passing buffer to RX channel"); cont.handler = buffer_passed_cb; struct bulk_buffer *buf = bulk_alloc_new_buffer(&allocator_rx); wait_cond = 1; while (buf) { err = bulk_channel_pass(&c->rx_chan, buf, NULL, cont); if (err_is_fail(err)) { USER_PANIC_ERR(err, "failed to pass the buffer"); } buf = bulk_alloc_new_buffer(&allocator_rx); thread_yield(); } wait_for_condition(); BS_NET_DEBUG_BULK("%s", "All buffers passed."); block_send_status_msg(c, BLOCK_NET_MSG_INIT, 0, BLOCK_NET_ERR_OK); BS_NET_DEBUG_BULK("%s", "Initialization done.\n\n\n"); }