📄 sdp_server.c
字号:
/* * sdp_server.c -- Application for browsing the sdp-database stored in an XML * file * * Copyright (C) 2000, 2001 Axis Communications AB * * Author: Mats Friden <mats.friden@axis.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. * * Exceptionally, Axis Communications AB grants discretionary and * conditional permissions for additional use of the text contained * in the company's release of the AXIS OpenBT Stack under the * provisions set forth hereunder. * * Provided that, if you use the AXIS OpenBT Stack with other files, * that do not implement functionality as specified in the Bluetooth * System specification, to produce an executable, this does not by * itself cause the resulting executable to be covered by the GNU * General Public License. Your use of that executable is in no way * restricted on account of using the AXIS OpenBT Stack code with it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the provisions of the GNU * General Public License. * * $Id: sdp_server.c,v 1.30 2001/08/22 17:46:37 mattiasagren Exp $ * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <syslog.h>#include <unistd.h>#include "xmlparse.h"#include "sdp_server.h"#include "sdp_parser.h"#ifdef BTD_USERSTACK#define syslog(x, fmt...) do { fprintf(stderr, __FILE__ "::"); fprintf(stderr, fmt); fprintf(stderr, "\n"); } while (0)#endif/* Does printouts in all functions called by expat */#define SDP_DEBUG_SUBFNC 0/* Does debug printouts in functions related to incomming data from the sdp parts in the kernel */#define SDP_DEBUG_INCOMING 0/* Other misc functions such as get_values, char2hex etc */#define SDP_DEBUG_MISC 0/* Debug for the get attribute functions */#define SDP_DEBUG_GET_ATTRIBUTES 0/* Debug for the get record handle functions */#define SDP_DEBUG_GET_RECORD_HDL 0/* Debug all malloc and free commands */#define SDP_DEBUG_MEM 0/* Printouts data in hex format */#define SDP_DEBUG_PRINT_DATA 0#if SDP_DEBUG_SUBFNC#define S_FNC(fmt...) syslog(LOG_INFO, __FUNCTION__ ": " fmt)#else#define S_FNC(fmt...)#endif#if SDP_DEBUG_INCOMING#define D_REC(fmt...) syslog(LOG_INFO, __FUNCTION__ ": " fmt)#else#define D_REC(fmt...)#endif#if SDP_DEBUG_MISC#define D_MISC(fmt...) syslog(LOG_INFO, __FUNCTION__ ": " fmt)#else#define D_MISC(fmt...)#endif#if SDP_DEBUG_GET_ATTRIBUTES#define D_ATTR(fmt...) syslog(LOG_INFO, __FUNCTION__ ": " fmt)#else#define D_ATTR(fmt...)#endif#if SDP_DEBUG_GET_RECORD_HDL#define D_RHDL(fmt...) syslog(LOG_INFO, __FUNCTION__ ": " fmt)#else#define D_RHDL(fmt...)#endif#if SDP_DEBUG_MEM#define D_MEM(fmt...) syslog(LOG_INFO, __FUNCTION__ ": " fmt)#else#define D_MEM(fmt...)#endif#if SDP_DEBUG_PRINT_DATA#define PRINT_DATA(str, data, len) print_data(str, data, len)#else#define PRINT_DATA(str, data, len)#endifvoid start_xml_parser(XML_Parser p, int fd);void char2hex(const char *char_data, unsigned char* buf);char* get_values(char *value_string, int value_string_len, int fd);void set_sdp_hdr(unsigned char *hdr, unsigned char pkt_type, unsigned short trans_id, unsigned short len);unsigned int* remove_duplicated_rec_hdl(unsigned int *rec_hdl_list_in, unsigned int cnt_in);unsigned int* get_all_rec_hdl(unsigned int *service_class_list, unsigned int service_class_cnt);unsigned int get_record_handle(unsigned short service_class, int fd);char* get_attribute_range(int fd, unsigned int record_handle, unsigned int attr_id_code);char* get_attribute_list(int fd, unsigned int record_handle, unsigned short attr_id_code);void get_attribute_list_start(void *data, const char *el, const char **attr);void get_attribute_list_end(void *data, const char *el);void get_attribute_char_data(void *userData,const XML_Char *s, int len);char* get_from_xml(int fd, char *tag, char *attr, unsigned char *val);void get_start(void *data, const char *el, const char **attr);void get_end(void *data, const char *el);int* get_all_attributes(int fd);void get_all_start(void *data, const char *el, const char **attr);void get_all_end(void *data, const char *el);void handle_query(database_query_struct *db_hdl);void handle_service_search_req(service_search_struct *db_hdl); void handle_service_attr_req(service_attr_struct *db_hdl);void handle_service_search_attr_req(service_search_attr_struct *db_hdl);int set_cont_state_attr(unsigned char *pkt, int len, int max_attr_len);int set_cont_state_search(unsigned char *pkt, unsigned int len, unsigned int max_rec_cnt);static int xml_fd;static int parse_err;extern int malloc_dbg;/* pointers to contionuationstate data */extern cont_state_struct *cont_state_buf;voidprint_data(const char *message, const unsigned char *buf, int len){ int t, offs = 0; char tmp[100]; syslog(LOG_INFO, "%s (%d):", message, len); for (t = 0; t < len; t++) { offs += sprintf(tmp + offs, " 0x%02x", (unsigned int)buf[t]); if (!((t+1) % 8)) { syslog(LOG_INFO, tmp); offs = 0; } } if (offs) { syslog(LOG_INFO, tmp); }}voidinit_sdp_server(int fd){ xml_fd = fd;}voidset_err(int err){ parse_err = err;}intget_err(void){ int tmp = parse_err; parse_err = 0; return tmp;}intis_err(void){ return parse_err != 0;}voidstart_xml_parser(XML_Parser p, int fd){ void *buf; int len; lseek(fd, 0, SEEK_SET); do { buf = XML_GetBuffer(p, BUFFSIZE); if (buf == NULL) { syslog(LOG_ERR, "start_xml_parser: couldn't get a free buffer"); break; } len = read(fd, buf, BUFFSIZE); if (len < 0) { fprintf(stderr, "start_xml_parser: error when reading xml file\n"); break; } if (!XML_ParseBuffer(p, len, len == 0)) { fprintf(stderr, "Parse error at line %d, col %d:\n%s\n", XML_GetCurrentLineNumber(p), XML_GetCurrentColumnNumber(p), XML_ErrorString(XML_GetErrorCode(p))); fprintf(stderr, "len: %d\n", len); break; } if (is_err()) { break; } } while (len);}voidchar2hex(const char *char_data, unsigned char* buf){ int i; int tmp; /* FIXME, How will this work when using big endian ? */ for (i = 0; i < strlen(char_data) / 2; i++) { sscanf(char_data + i * 2, "%02x", &tmp); buf[i] = (unsigned char)(tmp & 0xff); }}char*get_values(char *value_string, int value_string_len, int fd){ int value_string_pos = 0; static char tmp_list[256]; char tmp_len = 0; char *des_pos[DES_HDR_DEPTH]; /* des stands for Data Element Sequence */ int des_len[DES_HDR_DEPTH]; char c_des_len[3][DES_HDR_DEPTH]; int i; D_MISC(__FUNCTION__" value_string _%s_, valstrlen:%d\n", value_string, value_string_len); i = 0; while (i < value_string_len) { D_MISC("%s", value_string + i); i += strlen(value_string + i) + 1; } for (i = 0; i < DES_HDR_DEPTH; i++) { des_pos[i] = NULL; } /* While we have not reached the end of the string */ while (value_string_pos < value_string_len) { /* If we found a hex value instead of a string */ if (strncmp(value_string + value_string_pos, "0x", 2) == 0) { D_MISC("Found HEX val\n"); strcpy(tmp_list + tmp_len, value_string + value_string_pos + 2); tmp_len += strlen(value_string + value_string_pos) - 2; /* If we found a data element sequence header we need to remember that position so we can fill in the length field later */ if (strncmp(value_string + value_string_pos, S_DES_HDR, strlen(S_DES_HDR)) == 0) { unsigned int pos; unsigned int j; pos = strtoul(value_string + value_string_pos + strlen(S_DES_HDR), NULL, 16); /* Now we found a data element sequence header inside another data element sequence */ if (des_pos[pos]) { sprintf(c_des_len[pos], "%02x", des_len[pos]); D_MISC("c_des_len[%d]: %s", pos, c_des_len[pos]); strncpy(des_pos[pos], c_des_len[pos], 2); D_MISC("des_pos[%d]: %s", pos, des_pos[pos]); } des_pos[pos] = tmp_list + tmp_len - 2; des_len[pos] = 0; for (j = pos; j > 0; j--) { des_len[0] += (strlen(value_string + value_string_pos) - 2) / 2; } } else { des_len[1] += (strlen(value_string + value_string_pos) - 2) / 2; des_len[0] += (strlen(value_string + value_string_pos) - 2) / 2; } } else /* Here we found a string, and have to find the hex value for it in the database */ { char *tmp_code; D_MISC("Searching xml file : TAG SDPTranslationRegister\n"); D_MISC("String : _%s_\n", value_string+value_string_pos); /* Get the hex code for the attribute from the xml file */ tmp_code = get_from_xml(fd, "SDPTranslationRegister", value_string + value_string_pos, NULL); if (tmp_code == NULL) { D_MISC("Didn't find the hex code for: %s", value_string + value_string_pos); } else { int tmp; /* Copy the hex value to the temporary attribute list and increas the counters */ strcpy(tmp_list + tmp_len, tmp_code); tmp = strlen(tmp_code); tmp_len += tmp; des_len[1] += tmp / 2; des_len[0] += tmp / 2; D_MISC("des_len[1]: %d", des_len[1]); D_MISC("Found %s", tmp_code); /* since get_from_xml allocates space for the reurn paramterer we have to do free here */ D_MEM("<--- free%d 0x%8p", --malloc_dbg, tmp_code); free(tmp_code); } } value_string_pos += strlen(value_string + value_string_pos) + 1; } for (i = 0; i < DES_HDR_DEPTH; i++) { if (des_pos[i]) { /* Convert the data element sequence length to charactes and copy it into the attribute list */ sprintf(c_des_len[i], "%02x", des_len[i]); strncpy(des_pos[i], c_des_len[i], 2); D_MISC("%s", des_pos[i]); D_MISC("c_des_len[%d]: %s",i, c_des_len[i]); } } D_MISC("return_list %s", tmp_list); return tmp_list;}void set_sdp_hdr(unsigned char *hdr, unsigned char pkt_type, unsigned short trans_id, unsigned short len){ hdr[SDP_HDR_TYPE] = pkt_type; hdr[SDP_HDR_TRANS_ID_MS] = SHORT2CHAR_MS(trans_id); hdr[SDP_HDR_TRANS_ID_LS] = SHORT2CHAR_LS(trans_id); hdr[SDP_HDR_LENGTH_MS] = SHORT2CHAR_MS(len); hdr[SDP_HDR_LENGTH_LS] = SHORT2CHAR_LS(len);}unsigned int*remove_duplicated_rec_hdl(unsigned int *rec_hdl_list_in, unsigned int cnt_in) { static unsigned int rec_hdl_list_out[128]; unsigned int i, j, cnt_out = 0; unsigned int existing = FALSE; for (i = 0; i < cnt_in; i++) { for (j = 0; j < cnt_out; j++) { if (rec_hdl_list_in[i] == rec_hdl_list_out[j]) { existing = TRUE; } } if(!existing) { rec_hdl_list_out[cnt_out] = rec_hdl_list_in[i]; D_RHDL(__FUNCTION__": |||燢eeping record_handle 0x%08x |||", rec_hdl_list_out[cnt_out]); cnt_out++; } existing = FALSE; } rec_hdl_list_out[cnt_out] = NO_REC_HDL; return rec_hdl_list_out;}unsigned int*get_all_rec_hdl(unsigned int *service_class_list, unsigned int service_class_cnt){ unsigned int rec_hdl_list[64]; unsigned int *tmp_hdl_list; unsigned int rec_hdl_cnt = 0; int i, j; D_RHDL(__FUNCTION__": Searching for %d UUID:s...", service_class_cnt); for (i = 0; i < service_class_cnt; i++) { D_RHDL(__FUNCTION__": Now search for UUID : 0x%08x", service_class_list[i]); if ((rec_hdl_list[rec_hdl_cnt] = get_record_handle(service_class_list[i], xml_fd)) != NO_REC_HDL) { D_REC("Found record handle : 0x%08x", rec_hdl_list[rec_hdl_cnt]); rec_hdl_cnt++; } tmp_hdl_list = get_more_rec_hdl(service_class_list[i], xml_fd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -