📄 obex_client.c
字号:
/* Affix - Bluetooth Protocol Stack for Linux Copyright (C) 2001 Nokia Corporation Dmitry Kasatkin <dmitry.kasatkin@nokia.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//* $Id: obex_client.c,v 1.33 2003/03/03 11:37:46 kds Exp $ OBEX client lib Fixes: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>*/#include <affix/config.h>#include <stdint.h>#include <string.h>#include <stdlib.h>#include <libgen.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/mman.h>#include <arpa/inet.h>#include <netdb.h>#include <netinet/in.h>#include <stdio.h>#include <unistd.h>#include <errno.h>#include <affix/bluetooth.h>#include <affix/btcore.h>// OBEX stuff#include <openobex/obex.h>#include <affix/obex.h>obex_target_t file_target = {16, "\xF9\xEC\x7B\xC4\x95\x3C\x11\xD2\x98\x4E\x52\x54\x00\xDC\x9E\x09"};void _obex_error(char *buf, int err){ if (err < 0) sprintf(buf, "System error: %s (%d)", strerror(errno), errno); else if (err > 0) sprintf(buf, "OBEX error: %s (%d)", OBEX_ResponseToString(err), err); else sprintf(buf, "No error (0)");}char *obex_error(int err){ static unsigned char buf[80][2]; static int num = 0; num = 1 - num; /* switch buf */ _obex_error(buf[num], err); return buf[num];}/* obex client library */obex_file_t *obex_create_file(char *name){ obex_file_t *file; file = malloc(sizeof(obex_file_t)); if (!file) return NULL; if (!name) { file->name = strdup("/tmp/obex_tmp_XXXXXX"); if (!file->name) { free(file); return NULL; } file->fd = mkstemp(file->name); } else { file->name = strdup(name); if (!file->name) { free(file); return NULL; } file->fd = open(file->name, O_RDONLY); } if (file->fd < 0) { free(file->name); free(file); return NULL; } file->map_size = 0; return file;}void obex_close_file(obex_file_t *file){ if (file->map_size) munmap(file->map, file->map_size); if (file->fd >= 0) { close(file->fd); file->fd = -1; }}void obex_destroy_file(obex_file_t *file, int del){ obex_close_file(file); if (del) unlink(file->name); free(file->name); free(file);}int obex_open_file(obex_file_t *file){ if (file->fd >= 0) return lseek(file->fd, 0, SEEK_SET); else return (file->fd = open(file->name, O_RDONLY));}char *obex_map_file(obex_file_t *file){ if (obex_open_file(file) < 0) return NULL; file->map_size = get_fdsize(file->fd); file->map = mmap(0, file->map_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, file->fd, 0); if (file->map == MAP_FAILED) return NULL; return file->map;} void obexclt_connect(obex_t *handle, obex_object_t *object, int obex_rsp){ obex_headerdata_t hv; uint8_t hi; int hlen; uint8_t *nonhdrdata; const uint8_t *who = NULL; int who_len = 0; obexclt_t *clt = OBEX_GetUserData(handle); DBPRT(""); clt->rsp = obex_rsp; if (obex_rsp != OBEX_RSP_SUCCESS) return; if(OBEX_ObjectGetNonHdrData(object, &nonhdrdata) == 4) { DBPRT("Version: 0x%02x. Flags: 0x%02x OBEX packet length:%d", nonhdrdata[0], nonhdrdata[1], *(uint16_t*)&(nonhdrdata[2])); } else { BTERROR("Invalid packet content."); } while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch (hi) { case OBEX_HDR_WHO: who = hv.bs; who_len = hlen; DBPRT("got WHO: %*s, len: %d", who_len, who, who_len); break; case OBEX_HDR_CONNECTION: clt->conid = hv.bq4; DBPRT("got Conection ID: %#x\n", hv.bq4); break; default: DBPRT(" Skipped header %02x", hi); break; } }}void obexclt_get(obex_t *handle, obex_object_t *object, int obex_rsp){ obex_headerdata_t hv; uint8_t hi; int hlen; char *body = NULL; int body_len = 0; int len; obexclt_t *clt = OBEX_GetUserData(handle); DBPRT(""); clt->rsp = obex_rsp; if (obex_rsp != OBEX_RSP_SUCCESS) return; while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch (hi) { case OBEX_HDR_LENGTH: len = hv.bq4; DBPRT("got LENGTH"); break; case OBEX_HDR_BODY: //DBPRT("%*s\n", hlen, hv.bs); body = (char*)hv.bs; body_len = hlen; DBPRT("got BODY: %d", body_len); break; case OBEX_HDR_BODY_END: DBPRT("got BODYEND"); break; case OBEX_HDR_CONNECTION: DBPRT("got CONNECTION"); break; case OBEX_HDR_NAME: DBPRT("got NAME"); break; default: DBPRT(" Skipped header %02x", hi); break; } }}void obexclt_put(obex_t *handle, obex_object_t *object, int obex_rsp){ obex_headerdata_t hv; uint8_t hi; int hlen; obexclt_t *clt = OBEX_GetUserData(handle); int len; DBPRT(""); clt->rsp = obex_rsp; if (obex_rsp != OBEX_RSP_SUCCESS) return; while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch (hi) { case OBEX_HDR_LENGTH: len = hv.bq4; DBPRT("got LENGTH"); break; case OBEX_HDR_CONNECTION: DBPRT("got CONNECTION"); break; case OBEX_HDR_NAME: DBPRT("got NAME"); break; default: DBPRT(" Skipped header %02x", hi); } }}void obexclt_setpath(obex_t *handle, obex_object_t *object, int obex_rsp){ obex_headerdata_t hv; uint8_t hi; int hlen; obexclt_t *clt = OBEX_GetUserData(handle); DBPRT(""); clt->rsp = obex_rsp; if (obex_rsp != OBEX_RSP_SUCCESS) return; while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch (hi) { case OBEX_HDR_CONNECTION: DBPRT("got CONNECTION"); break; case OBEX_HDR_NAME: DBPRT("got NAME"); break; default: DBPRT(" Skipped header %02x", hi); break; } }}void request_done(obex_t *handle, obex_object_t *object, int obex_cmd, int obex_rsp){ obexclt_t *clt = OBEX_GetUserData(handle); DBPRT("Command (%02x) has now finished, rsp: %02x", obex_cmd, obex_rsp); switch (obex_cmd) { case OBEX_CMD_DISCONNECT: DBPRT("Disconnect done!"); OBEX_TransportDisconnect(handle); clt->clientdone = TRUE; break; case OBEX_CMD_CONNECT: DBPRT("Connected!\n"); obexclt_connect(handle, object, obex_rsp); clt->clientdone = TRUE; break; case OBEX_CMD_GET: obexclt_get(handle, object, obex_rsp); clt->clientdone = TRUE; break; case OBEX_CMD_PUT: obexclt_put(handle, object, obex_rsp); clt->clientdone = TRUE; break; case OBEX_CMD_SETPATH: obexclt_setpath(handle, object, obex_rsp); clt->clientdone = TRUE; break; default: DBPRT("Command (%02x) has now finished", obex_cmd); break; }}int obex_request(obexclt_t *clt, obex_object_t *object){ int err = 0; err = OBEX_Request(clt->handle, object); if (err) return err; clt->clientdone = FALSE; while (!clt->clientdone) { if ((err = OBEX_HandleInput(clt->handle, 1)) < 0) { BTERROR("Error while doing OBEX_HandleInput()"); break; } err = (clt->rsp == OBEX_RSP_SUCCESS)?0:clt->rsp; } return err;}//// Add more data to stream.//static int writestream(obex_t *handle, obex_object_t *object){ int actual; obexclt_t *clt = OBEX_GetUserData(handle); obex_headerdata_t hv; actual = read(clt->sfd, clt->buf, OBEX_STREAM_CHUNK); //DBPRT("send %d bytes\n", actual); if(actual > 0) { /* Read was ok! */ hv.bs = clt->buf; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hv, actual, OBEX_FL_STREAM_DATA); } else if(actual == 0) { /* EOF */ hv.bs = clt->buf; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hv, 0, OBEX_FL_STREAM_DATAEND); } else { /* Error */ hv.bs = NULL; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hv, 0, OBEX_FL_STREAM_DATA); } return actual;}//// Read data from stream.//static int readstream(obex_t *handle, obex_object_t *object){ int actual; obexclt_t *clt = OBEX_GetUserData(handle); const uint8_t *buf; int len; actual = OBEX_ObjectReadStream(handle, object, &buf); //DBPRT("Got %d bytes\n", actual); if (actual > 0) { len = write(clt->sfd, buf, actual); } return actual;}//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -