/* * Function obex_object_receive_stream() * * Handle receiving of body-stream * */ static void obex_object_receive_stream(obex_t *self, uint8_t hi, uint8_t *source, unsigned int len) { obex_object_t *object = self->object; DEBUG(4, "\n"); /* Spare the app this empty nonlast body-hdr */ if (hi == OBEX_HDR_BODY && len == 0) return; object->s_buf = source; object->s_len = len; if (object->abort) { DEBUG(3, "Ignoring incomming data because request was aborted\n"); return; } /* Notify app that data has arrived */ obex_deliver_event(self, OBEX_EV_STREAMAVAIL, 0, 0, FALSE); /* If send send EOS to app */ if (hi == OBEX_HDR_BODY_END && len != 0) { object->s_buf = source; object->s_len = 0; obex_deliver_event(self, OBEX_EV_STREAMAVAIL, 0, 0, FALSE); } }
int obex_object_resume(obex_t *self, obex_object_t *object) { int ret; if (!object->suspend) return 0; object->suspend = 0; if (object->first_packet_sent && !object->continue_received) return 0; ret = obex_object_send(self, object, TRUE, FALSE); if (ret < 0) { obex_deliver_event(self, OBEX_EV_LINKERR, object->opcode & ~OBEX_FINAL, 0, TRUE); return -1; } else if (ret == 0) { obex_deliver_event(self, OBEX_EV_PROGRESS, object->opcode & ~OBEX_FINAL, 0, FALSE); object->first_packet_sent = 1; object->continue_received = 0; } else { if (self->state & MODE_SRV) { obex_deliver_event(self, OBEX_EV_REQDONE, object->opcode & ~OBEX_FINAL, 0, TRUE); self->state = MODE_SRV | STATE_IDLE; return 0; } } if (self->state & MODE_SRV) self->state = MODE_SRV | STATE_REC; else self->state = MODE_CLI | STATE_REC; return 0; }
/* * Function obex_transport_handle_input(self, timeout) * * Used when working in synchronous mode. * */ int obex_transport_handle_input(obex_t *self, int timeout) { int ret; if (self->trans.type == OBEX_TRANS_CUSTOM) { if (self->ctrans.handleinput) ret = self->ctrans.handleinput(self, self->ctrans.customdata, timeout); else { DEBUG(4, "No handleinput-callback exist!\n"); ret = -1; } } else if (self->trans.type == OBEX_TRANS_USB && self->fd == INVALID_SOCKET) ret = obex_data_indication(self, NULL, 0); else { struct timeval time; fd_set fdset; socket_t highestfd = 0; DEBUG(4, "\n"); obex_return_val_if_fail(self != NULL, -1); /* Check of we have any fd's to do select on. */ if (self->fd == INVALID_SOCKET && self->serverfd == INVALID_SOCKET) { DEBUG(0, "No valid socket is open\n"); return -1; } time.tv_sec = timeout; time.tv_usec = 0; /* Add the fd's to the set. */ FD_ZERO(&fdset); if (self->fd != INVALID_SOCKET) { FD_SET(self->fd, &fdset); if (self->fd > highestfd) highestfd = self->fd; } if (self->serverfd != INVALID_SOCKET) { FD_SET(self->serverfd, &fdset); if (self->serverfd > highestfd) highestfd = self->serverfd; } /* Wait for input */ if (timeout >= 0) { ret = select((int)highestfd+1, &fdset, NULL, NULL, &time); } else { ret = select((int)highestfd+1, &fdset, NULL, NULL, NULL); } /* Check if this is a timeout (0) or error (-1) */ if (ret < 1) return ret; if (self->fd != INVALID_SOCKET && FD_ISSET(self->fd, &fdset)) { DEBUG(4, "Data available on client socket\n"); ret = obex_data_indication(self, NULL, 0); } else if (self->serverfd != INVALID_SOCKET && FD_ISSET(self->serverfd, &fdset)) { DEBUG(4, "Data available on server socket\n"); /* Accept : create the connected socket */ ret = obex_transport_accept(self); /* Tell the app to perform the OBEX_Accept() */ if (self->keepserver) obex_deliver_event(self, OBEX_EV_ACCEPTHINT, 0, 0, FALSE); /* Otherwise, just disconnect the server */ if (ret >= 0 && !self->keepserver) obex_transport_disconnect_server(self); } else ret = -1; } return ret; }
/* * Function send_stream(object, header, txmsg, tx_left) * * Send a streaming header. * */ static int send_stream(obex_t *self, struct obex_header_element *h, buf_t *txmsg, unsigned int tx_left) { obex_object_t *object; struct obex_byte_stream_hdr *body_txh; int actual; /* Number of bytes sent in this fragment */ DEBUG(4, "\n"); object = self->object; /* Fill in length and header type later, but reserve space for it */ body_txh = (struct obex_byte_stream_hdr*) buf_reserve_end(txmsg, sizeof(struct obex_byte_stream_hdr) ); tx_left -= sizeof(struct obex_byte_stream_hdr); actual = sizeof(struct obex_byte_stream_hdr); do { if (object->s_len == 0) { /* Ask app for more data if no more */ object->s_offset = 0; object->s_buf = NULL; obex_deliver_event(self, OBEX_EV_STREAMEMPTY, 0, 0, FALSE); DEBUG(4, "s_len=%d, s_stop = %d\n", object->s_len, object->s_stop); /* End of stream ?*/ if (object->s_stop) break; /* User suspended and didn't provide any new data */ if (object->suspend && object->s_buf == NULL) break; /* Error ?*/ if (object->s_buf == NULL) { DEBUG(1, "Unexpected end-of-stream\n"); return -1; } } if (tx_left < object->s_len) { /* There is more data left in buffer than tx_left */ DEBUG(4, "More data than tx_left. Buffer will not be empty\n"); buf_insert_end(txmsg, (uint8_t*) object->s_buf + object->s_offset, tx_left); object->s_len -= tx_left; object->s_offset += tx_left; actual += tx_left; tx_left = 0; } else { /* There less data in buffer than tx_left */ DEBUG(4, "Less data that tx_left. Buffer will be empty\n"); buf_insert_end(txmsg, (uint8_t*) object->s_buf + object->s_offset, object->s_len); tx_left -= object->s_len; object->s_offset += object->s_len; actual += object->s_len; object->s_len = 0; if (object->suspend) tx_left = 0; } } while (tx_left > 0); DEBUG(4, "txmsg full or no more stream-data. actual = %d\n", actual); body_txh->hi = OBEX_HDR_BODY; if (object->s_stop && object->s_len == 0) { /* We are done. Remove header from tx-queue */ object->tx_headerq = slist_remove(object->tx_headerq, h); body_txh->hi = OBEX_HDR_BODY_END; buf_free(h->buf); free(h); } body_txh->hl = htons((uint16_t)actual); return actual; }
/* * Function obex_data_indication (self) * * Read/Feed some input from device and find out which packet it is * */ int obex_data_indication(obex_t *self, uint8_t *buf, int buflen) { obex_common_hdr_t *hdr; buf_t *msg; int final; int actual = 0; unsigned int size; int ret; DEBUG(4, "\n"); obex_return_val_if_fail(self != NULL, -1); msg = self->rx_msg; if (self->trans.fmt == OBEX_MT_SEQPACKET) { actual = obex_transport_read(self, msg->data_avail, buf, buflen); DEBUG(4, "Got %d bytes\n", actual); if (buf == NULL && buflen == 0 && actual <= 0) { obex_deliver_event(self, OBEX_EV_LINKERR, 0, 0, TRUE); return actual; } hdr = (obex_common_hdr_t *) msg->data; size = ntohs(hdr->len); } else { /* First we need 3 bytes to be able to know how much data to read */ if(msg->data_size < 3) { actual = obex_transport_read(self, 3 - (msg->data_size), buf, buflen); DEBUG(4, "Got %d bytes\n", actual); /* Check if we are still connected */ /* do not error if the data is from non-empty but partial buffer (custom transport) */ if (buf == NULL && buflen == 0 && actual <= 0) { obex_deliver_event(self, OBEX_EV_LINKERR, 0, 0, TRUE); return actual; } buf += actual; buflen -= actual; } /* If we have 3 bytes data we can decide how big the packet is */ if(msg->data_size >= 3) { hdr = (obex_common_hdr_t *) msg->data; size = ntohs(hdr->len); actual = 0; if(msg->data_size < (int) ntohs(hdr->len)) { actual = obex_transport_read(self, size - msg->data_size, buf, buflen); /* hdr might not be valid anymore if the _read did a realloc */ hdr = (obex_common_hdr_t *) msg->data; /* Check if we are still connected */ /* do not error if the data is from non-empty but partial buffer (custom transport) */ if (buf == NULL && buflen == 0 && actual <= 0) { obex_deliver_event(self, OBEX_EV_LINKERR, 0, 0, TRUE); return actual; } } } else { /* Wait until we have at least 3 bytes data */ DEBUG(3, "Need at least 3 bytes got only %d!\n", msg->data_size); return actual; } } /* New data has been inserted at the end of message */ DEBUG(1, "Got %d bytes msg len=%d\n", actual, msg->data_size); /* * Make sure that the buffer we have, actually has the specified * number of bytes. If not the frame may have been fragmented, and * we will then need to read more from the socket. */ /* Make sure we have a whole packet */ if (size > msg->data_size) { DEBUG(3, "Need more data, size=%d, len=%d!\n", size, msg->data_size); /* I'll be back! */ return msg->data_size; } DUMPBUFFER(2, "Rx", msg); actual = msg->data_size; final = hdr->opcode & OBEX_FINAL; /* Extract final bit */
/* * Function obex_data_indication (self) * * Read/Feed some input from device and find out which packet it is * */ int obex_data_indication(obex_t *self, uint8_t *buf, int buflen) { obex_common_hdr_t *hdr; GNetBuf *msg; int final; int actual = 0; unsigned int size; int ret; DEBUG(4, "\n"); obex_return_val_if_fail(self != NULL, -1); msg = self->rx_msg; /* First we need 3 bytes to be able to know how much data to read */ if(msg->len < 3) { actual = obex_transport_read(self, 3 - (msg->len), buf, buflen); DEBUG(4, "Got %d bytes\n", actual); /* Check if we are still connected */ if (actual <= 0) { obex_deliver_event(self, OBEX_EV_LINKERR, 0, 0, TRUE); return actual; } buf += actual; buflen -= actual; g_netbuf_put(msg, actual); } /* If we have 3 bytes data we can decide how big the packet is */ if(msg->len >= 3) { hdr = (obex_common_hdr_t *) msg->data; size = ntohs(hdr->len); actual = 0; if(msg->len != (int) ntohs(hdr->len)) { actual = obex_transport_read(self, size - msg->len, buf, buflen); /* Check if we are still connected */ if (actual <= 0) { obex_deliver_event(self, OBEX_EV_LINKERR, 0, 0, TRUE); return actual; } } } else { /* Wait until we have at least 3 bytes data */ DEBUG(3, "Need at least 3 bytes got only %d!\n", msg->len); return actual; } /* New data has been inserted at the end of message */ g_netbuf_put(msg, actual); DEBUG(1, "Got %d bytes msg len=%d\n", actual, msg->len); /* * Make sure that the buffer we have, actually has the specified * number of bytes. If not the frame may have been fragmented, and * we will then need to read more from the socket. */ /* Make sure we have a whole packet */ if (size > msg->len) { DEBUG(3, "Need more data, size=%d, len=%d!\n", size, msg->len); /* I'll be back! */ return msg->len; } DUMPBUFFER(2, "Rx", msg); actual = msg->len; final = hdr->opcode & OBEX_FINAL; /* Extract final bit */