/** Read data from body stream. \param self OBEX handle \param object OBEX object \param buf A pointer to a pointer which this function will set to a buffer which shall be read (and ONLY read) after this function returns. \return number of bytes in buffer, or 0 for end-of-stream, -1 on error To recieve the body as a stream call this function with buf = NULL as soon as you get an #OBEX_EV_REQHINT event. You will now recieve #OBEX_EV_STREAMAVAIL events when data is available for you. Call this function to get the data. Note! When receiving a stream data is not buffered so if you don't call this function when you get an #OBEX_EV_STREAMAVAIL event data will be lost. */ LIB_SYMBOL int CALLAPI OBEX_ObjectReadStream(obex_t *self, obex_object_t *object, const uint8_t **buf) { obex_return_val_if_fail(self != NULL, -1); obex_return_val_if_fail(object != NULL, -1); return obex_object_readstream(self, object, buf); }
/** Allow the user to parse again the rx headers. \param self OBEX handle \param object OBEX object \return 1 on success, 0 if previous parsing not completed, -1 on error The user must have extracted all headers from the object before calling this function (until #OBEX_ObjectGetNextHeader() returns 0). Next call to #OBEX_ObjectGetNextHeader() will return the first received header. */ LIB_SYMBOL int CALLAPI OBEX_ObjectReParseHeaders(obex_t *self, obex_object_t *object) { obex_return_val_if_fail(self != NULL, -1); obex_return_val_if_fail(object != NULL, -1); return obex_object_reparseheaders(self, object); }
/** Connect USB interface. \param self OBEX handle \param intf USB interface to connect to \return -1 or negative error code on error An easier connect function to connect to a discovered interface (currently USB OBEX only). */ LIB_SYMBOL int CALLAPI OBEX_InterfaceConnect(obex_t *self, obex_interface_t *intf) { DEBUG(4, "\n"); obex_return_val_if_fail(self != NULL, -1); if (self->object) { DEBUG(1, "We are busy.\n"); return -EBUSY; } obex_return_val_if_fail(intf != NULL, -1); switch (self->trans.type) { case OBEX_TRANS_USB: obex_return_val_if_fail(intf->usb.intf != NULL, -1); #ifdef HAVE_USB usbobex_prepare_connect(self, intf->usb.intf); return obex_transport_connect_request(self); #else return -ESOCKTNOSUPPORT; #endif /* HAVE_USB */ default: return -ESOCKTNOSUPPORT; } }
/** Get available space in object. \param self OBEX handle \param object OBEX object to query \param flags OBEX_FL_FIT_ONE_PACKET or 0 \return -1 on error Returns the available space in a given obex object. This can be useful e.g. if the caller wants to check the size of the biggest body header that can be added to the current packet. */ LIB_SYMBOL int CALLAPI OBEX_ObjectGetSpace(obex_t *self, obex_object_t *object, unsigned int flags) { obex_return_val_if_fail(self != NULL, -1); obex_return_val_if_fail(object != NULL, -1); return obex_object_getspace(self, object, flags); }
/** Attach a header to an object. \param self OBEX handle \param object OBEX object \param hi Header identifier \param hv Header value \param hv_size Header size \param flags See obex.h for possible values \return -1 on error Add a new header to an object. If you want all headers to fit in one packet, use the flag #OBEX_FL_FIT_ONE_PACKET on all headers you add to an object. To stream a body add a body header with hv.bs = NULL and set the flag #OBEX_FL_STREAM_START. You will now get #OBEX_EV_STREAMEMPTY events as soon as the the parser wants you to feed it with more data. When you get an #OBEX_EV_STREAMEMPTY event give the parser some data by adding a body-header and set the flag #OBEX_FL_STREAM_DATA. When you have no more data to send set the flag #OBEX_FL_STREAM_DATAEND instead. After adding a header you are free to do whatever you want with the buffer if you are NOT streaming. If you are streaming you may not touch the buffer until you get another #OBEX_EV_STREAMEMPTY or until the request finishes. The headers will be sent in the order you add them. */ LIB_SYMBOL int CALLAPI OBEX_ObjectAddHeader(obex_t *self, obex_object_t *object, uint8_t hi, obex_headerdata_t hv, uint32_t hv_size, unsigned int flags) { obex_return_val_if_fail(self != NULL, -1); obex_return_val_if_fail(object != NULL, -1); return obex_object_addheader(self, object, hi, hv, hv_size, flags); }
/** Get next available header from an object. \param self OBEX handle \param object OBEX object \param hi Pointer to header identifier \param hv Pointer to hv \param hv_size Pointer to hv_size \return 0 when no more headers are available, -1 on error Returns 0 when no more headers are available. All headers are read-only. You will get the headers in the received order. */ LIB_SYMBOL int CALLAPI OBEX_ObjectGetNextHeader(obex_t *self, obex_object_t *object, uint8_t *hi, obex_headerdata_t *hv, uint32_t *hv_size) { obex_return_val_if_fail(self != NULL, -1); obex_return_val_if_fail(object != NULL, -1); return obex_object_getnextheader(self, object, hi, hv, hv_size); }
/** Register a custom transport. \param self OBEX handle \param ctrans Structure with callbacks to transport operations (see obex_const.h for details) \return -1 on error Call this function directly after #OBEX_Init if you are using a custom transport. */ LIB_SYMBOL int CALLAPI OBEX_RegisterCTransport(obex_t *self, obex_ctrans_t *ctrans) { obex_return_val_if_fail(self != NULL, -1); obex_return_val_if_fail(ctrans != NULL, -1); memcpy(&self->ctrans, ctrans, sizeof(obex_ctrans_t)); return 1; }
/** Feed OBEX with data when using a custom transport. \param self OBEX handle \param inputbuf Pointer to custom data \param actual Length of buffer \return -1 on error */ LIB_SYMBOL int CALLAPI OBEX_CustomDataFeed(obex_t *self, uint8_t *inputbuf, int actual) { DEBUG(3, "\n"); obex_return_val_if_fail(self != NULL, -1); obex_return_val_if_fail(inputbuf != NULL, -1); return obex_data_indication(self, inputbuf, actual); }
/** Start listening for incoming connections. \param self OBEX handle \param saddr Local address to bind to \param addrlen Length of address \return -1 on error Bind a server socket to an Obex service. Common transport have specialised version of this function. Note : between 0.9.8 and 0.10.0, the prototype of this function changed to make it generic. If you want your code to work across new and old version of OpenObex, you may use \#ifdef OBEX_MAXIMUM_MTU to test the Obex version. */ LIB_SYMBOL int CALLAPI OBEX_ServerRegister(obex_t *self, struct sockaddr *saddr, int addrlen) { DEBUG(3, "\n"); obex_return_val_if_fail(self != NULL, -1); obex_return_val_if_fail((addrlen == 0) || (saddr != NULL), -1); memcpy(&self->trans.self, saddr, addrlen); return obex_transport_listen(self); }
/** Try to connect to peer. \param self OBEX handle \param saddr Address to connect to \param addrlen Length of address \return -1 on error */ LIB_SYMBOL int CALLAPI OBEX_TransportConnect(obex_t *self, struct sockaddr *saddr, int addrlen) { DEBUG(4, "\n"); obex_return_val_if_fail(self != NULL, -1); obex_return_val_if_fail((addrlen == 0) || (saddr != NULL), -1); memcpy(&self->trans.peer, saddr, addrlen); return obex_transport_connect_request(self); }
/** Start listening for incoming connections. \param self OBEX handle \param service Service to bind to. \return -1 or negative error code on error An easier server function to use for IrDA (IrOBEX) only. */ LIB_SYMBOL int CALLAPI IrOBEX_ServerRegister(obex_t *self, const char *service) { DEBUG(3, "\n"); obex_return_val_if_fail(self != NULL, -1); obex_return_val_if_fail(service != NULL, -1); #ifdef HAVE_IRDA irobex_prepare_listen(self, service); return obex_transport_listen(self); #else return -ESOCKTNOSUPPORT; #endif /* HAVE_IRDA */ }
/** Set headeroffset. \param object OBEX object \param offset Desired offset \return 1 on success, -1 on error Call this function when you get a OBEX_EV_REQHINT and you know that the command has data before the headers comes. You do NOT need to use this function on Connect and SetPath, they are handled automatically. */ LIB_SYMBOL int CALLAPI OBEX_ObjectSetHdrOffset(obex_object_t *object, unsigned int offset) { obex_return_val_if_fail(object != NULL, -1); object->headeroffset = offset; return 1; }
/** Let the OBEX parser do some work. \param self OBEX handle \param timeout Maximum time to wait in seconds \return -1 on error, 0 on timeout, positive on success Let the OBEX parser read and process incoming data. If no data is available this call will block. When a request has been sent or you are waiting for an incoming server- request you should call this function until the request has finished. Like select() this function returns -1 on error, 0 on timeout or positive on success. */ LIB_SYMBOL int CALLAPI OBEX_HandleInput(obex_t *self, int timeout) { DEBUG(4, "\n"); obex_return_val_if_fail(self != NULL, -1); return obex_transport_handle_input(self, timeout); }
/** Set MTU to be used for receive and transmit. \param self OBEX handle \param mtu_rx maximum receive transport packet size \param mtu_tx_max maximum transmit transport packet size negociated \return -1 or negative error code on error Changing those values can increase the performance of the underlying transport, but will increase memory consumption and latency (especially abort latency), and may trigger bugs in buggy transport. This need to be set *before* establishing the connection. */ LIB_SYMBOL int CALLAPI OBEX_SetTransportMTU(obex_t *self, uint16_t mtu_rx, uint16_t mtu_tx_max) { obex_return_val_if_fail(self != NULL, -EFAULT); if (self->object) { DEBUG(1, "We are busy.\n"); return -EBUSY; } if (mtu_rx < OBEX_MINIMUM_MTU /*|| mtu_rx > OBEX_MAXIMUM_MTU*/) return -E2BIG; if (mtu_tx_max < OBEX_MINIMUM_MTU /*|| mtu_tx_max > OBEX_MAXIMUM_MTU*/) return -E2BIG; /* Change MTUs */ self->mtu_rx = mtu_rx; self->mtu_tx_max = mtu_tx_max; /* Reallocate transport buffers */ buf_resize(self->rx_msg, self->mtu_rx); if (self->rx_msg == NULL) return -ENOMEM; buf_resize(self->tx_msg, self->mtu_tx_max); if (self->tx_msg == NULL) return -ENOMEM; return 0; }
/** Get FD. \param self OBEX handle \return file descriptor of the transport, -1 on error Returns the filedescriptor of the transport. Returns -1 on error. Note that if you for example have a custom transport, no fd is available. The returned filehandle can be used to do select() on, before calling OBEX_HandleInput() There is one subtelty about this function. When the OBEX connection is established, it returns the connection filedescriptor, while for an unconnected server it will return the listening filedescriptor. This mean that after receiving an incomming connection, you need to call this function again. */ LIB_SYMBOL int CALLAPI OBEX_GetFD(obex_t *self) { obex_return_val_if_fail(self != NULL, -1); if(self->fd == INVALID_SOCKET) return self->serverfd; return self->fd; }
/** Disconnect transport. \param self OBEX handle \return -1 on error */ LIB_SYMBOL int CALLAPI OBEX_TransportDisconnect(obex_t *self) { DEBUG(4, "\n"); obex_return_val_if_fail(self != NULL, -1); obex_transport_disconnect_request(self); return 0; }
/** Get the OBEX commmand of an object. \param self OBEX context \param object OBEX object (or NULL to access the current object) \return -1 on error Call this function to get the OBEX command of an object. */ LIB_SYMBOL int CALLAPI OBEX_ObjectGetCommand(obex_t *self, obex_object_t *object) { obex_return_val_if_fail(object != NULL || self->object != NULL, -1); if (object) return object->cmd; return self->object->cmd; }
/** Set data to send before headers. \param object OBEX object \param buffer Data to send \param len Length to data \return 1 on success, -1 on error Some commands (notably SetPath) send data before headers. Use this function to set this data. */ LIB_SYMBOL int CALLAPI OBEX_ObjectSetNonHdrData(obex_object_t *object, const uint8_t *buffer, unsigned int len) { /* TODO: Check that we actually can send len bytes without violating MTU */ obex_return_val_if_fail(object != NULL, -1); obex_return_val_if_fail(buffer != NULL, -1); if (object->tx_nonhdr_data) return -1; object->tx_nonhdr_data = buf_new(len); if (object->tx_nonhdr_data == NULL) return -1; buf_insert_end(object->tx_nonhdr_data, (uint8_t *)buffer, len); return 1; }
/** Start a request (as client). \param self OBEX handle \param object Object containing request \return -1 or negative error code on error */ LIB_SYMBOL int CALLAPI OBEX_Request(obex_t *self, obex_object_t *object) { DEBUG(4, "\n"); obex_return_val_if_fail(self != NULL, -1); if (self->object) { DEBUG(1, "We are busy.\n"); return -EBUSY; } obex_return_val_if_fail(object != NULL, -1); self->object = object; self->state = STATE_START | MODE_CLI; return obex_client(self, NULL, 0); }
/** Get any data which was before headers. \param object OBEX object \param buffer Pointer to a pointer which will point to a read-only buffer \return size of the buffer or -1 for error */ LIB_SYMBOL int CALLAPI OBEX_ObjectGetNonHdrData(obex_object_t *object, uint8_t **buffer) { obex_return_val_if_fail(object != NULL, -1); if (!object->rx_nonhdr_data) return 0; *buffer = object->rx_nonhdr_data->data; return object->rx_nonhdr_data->data_size; }
obex_interface_t * CALLAPI OBEX_GetInterfaceByIndex(obex_t *self, int i) { DEBUG(4, "\n"); obex_return_val_if_fail(self != NULL, NULL); if (i >= self->interfaces_number || i < 0) return NULL; return &self->interfaces[i]; }
/* * Function obex_data_request (self, opcode, cmd) * * Send response or command code along with optional headers/data. * */ int obex_data_request(obex_t *self, buf_t *msg, int opcode) { obex_common_hdr_t *hdr; int actual = 0; obex_return_val_if_fail(self != NULL, -1); obex_return_val_if_fail(msg != NULL, -1); /* Insert common header */ hdr = (obex_common_hdr_t *) buf_reserve_begin(msg, sizeof(obex_common_hdr_t)); hdr->opcode = opcode; hdr->len = htons((uint16_t)msg->data_size); DUMPBUFFER(1, "Tx", msg); DEBUG(1, "len = %d bytes\n", msg->data_size); actual = obex_transport_write(self, msg); return actual; }
/** Simple unicode to char function. \param c Destination (char) \param uc Source (unicode) \param size Length of destination buffer, at least half the size of source \return -1 on error Buffers may not overlap. Returns -1 on error. */ LIB_SYMBOL int CALLAPI OBEX_UnicodeToChar(uint8_t *c, const uint8_t *uc, int size) { int n; DEBUG(4, "\n"); obex_return_val_if_fail(uc != NULL, -1); obex_return_val_if_fail(c != NULL, -1); /* Make sure buffer is big enough! */ for (n = 0; uc[n*2+1] != 0; n++); obex_return_val_if_fail(n < size, -1); for (n = 0; uc[n*2+1] != 0; n++) c[n] = uc[n*2+1]; c[n] = 0; return 0; }
/** Start listening for incoming TCP connections. \param self OBEX handle \param addr Address to bind to (*:650 if NULL) \param addrlen Length of address structure \return -1 on error An easier server function to use for TCP/IP (TcpOBEX) only. It supports IPv4 (AF_INET) and IPv6 (AF_INET6). Note: INADDR_ANY will get mapped to IN6ADDR_ANY and using port 0 will select the default OBEX port. */ LIB_SYMBOL int CALLAPI TcpOBEX_ServerRegister(obex_t *self, struct sockaddr *addr, int addrlen) { DEBUG(3, "\n"); errno = EINVAL; obex_return_val_if_fail(self != NULL, -1); inobex_prepare_listen(self, addr, addrlen); return obex_transport_listen(self); }
/** Simple char to unicode function. \param uc Destination (unicode) \param c Source (char) \param size Length of destination buffer, at least twice the size of source \return -1 on error Buffers may not overlap. Returns -1 on error. */ LIB_SYMBOL int CALLAPI OBEX_CharToUnicode(uint8_t *uc, const uint8_t *c, int size) { int len, n; DEBUG(4, "\n"); obex_return_val_if_fail(uc != NULL, -1); obex_return_val_if_fail(c != NULL, -1); len = n = strlen((char *) c); obex_return_val_if_fail(n*2+2 <= size, -1); uc[n*2+1] = 0; uc[n*2] = 0; while (n--) { uc[n*2+1] = c[n]; uc[n*2] = 0; } return (len * 2) + 2; }
/** Connect Bluetooth transport. \param self OBEX handle \param src source address to connect from \param dst destination address to connect to \param channel destination channel to connect to \return -1 or negative error code on error An easier connect function to use for Bluetooth (Bluetooth OBEX) only. */ LIB_SYMBOL int CALLAPI BtOBEX_TransportConnect(obex_t *self, bdaddr_t *src, bdaddr_t *dst, uint8_t channel) { DEBUG(4, "\n"); obex_return_val_if_fail(self != NULL, -1); if (self->object) { DEBUG(1, "We are busy.\n"); return -EBUSY; } obex_return_val_if_fail(dst != NULL, -1); #ifdef HAVE_BLUETOOTH if (src == NULL) src = BDADDR_ANY; btobex_prepare_connect(self, src, dst, channel); return obex_transport_connect_request(self); #else return -ESOCKTNOSUPPORT; #endif /* HAVE_BLUETOOTH */ }
/** Start listening for incoming connections. \param self OBEX handle \param src source address to listen on \param channel source channel to listen on \return -1 or negative error code on error An easier server function to use for Bluetooth (Bluetooth OBEX) only. */ LIB_SYMBOL int CALLAPI BtOBEX_ServerRegister(obex_t *self, bdaddr_t *src, uint8_t channel) { DEBUG(3, "\n"); obex_return_val_if_fail(self != NULL, -1); #ifdef HAVE_BLUETOOTH if (src == NULL) src = BDADDR_ANY; btobex_prepare_listen(self, src, channel); return obex_transport_listen(self); #else return -ESOCKTNOSUPPORT; #endif /* HAVE_BLUETOOTH */ }
/* FdOBEX_TransportSetup - setup descriptors for OBEX_TRANS_FD transport. \param self OBEX handle \param rfd descriptor to read \param wfd descriptor to write \param mtu transport mtu: 0 - default \return -1 or negative error code on error */ LIB_SYMBOL int CALLAPI FdOBEX_TransportSetup(obex_t *self, int rfd, int wfd, int mtu) { DEBUG(4, "\n"); obex_return_val_if_fail(self != NULL, -1); if (self->object) { DEBUG(1, "We are busy.\n"); return -EBUSY; } self->fd = rfd; self->writefd = wfd; self->trans.mtu = mtu ? mtu : self->mtu_tx_max; return obex_transport_connect_request(self); }
/** Connect TCP transport. \param self OBEX handle \param addr Address to connect to ([::1]:650 if NULL) \param addrlen Length of address structure \return -1 on error An easier connect function to use for TCP/IP (TcpOBEX) only. It supports IPv4 (AF_INET) and IPv6 (AF_INET6). */ LIB_SYMBOL int CALLAPI TcpOBEX_TransportConnect(obex_t *self, struct sockaddr *addr, int addrlen) { DEBUG(4, "\n"); errno = EINVAL; obex_return_val_if_fail(self != NULL, -1); if (self->object) { DEBUG(1, "We are busy.\n"); errno = EBUSY; return -1; } inobex_prepare_connect(self, addr, addrlen); return obex_transport_connect_request(self); }
/** Connect Irda transport. \param self OBEX handle \param service IrIAS service name to connect to \return -1 or negative error code on error An easier connect function to use for IrDA (IrOBEX) only. */ LIB_SYMBOL int CALLAPI IrOBEX_TransportConnect(obex_t *self, const char *service) { DEBUG(4, "\n"); obex_return_val_if_fail(self != NULL, -1); if (self->object) { DEBUG(1, "We are busy.\n"); return -EBUSY; } #ifdef HAVE_IRDA irobex_prepare_connect(self, service); return obex_transport_connect_request(self); #else return -ESOCKTNOSUPPORT; #endif /* HAVE_IRDA */ }