📄 sdp_server.c
字号:
for (i = 0; attr[i]; i += 2) { /* If there are a number of following entities, we have found a data element sequence */ if (strcmp(attr[i], "NbrOfEntities") == 0) { search_struct->attr2get = atoi(attr[i + 1]); S_FNC("attr2get: %d", atoi(attr[i + 1])); /* Set the data element sequence header */ strcpy(search_struct->attrlist + search_struct->attrlist_index, S_DES_HDR0); search_struct->attrlist_index += strlen(S_DES_HDR0) + 1; } /* Otherwise the wole attribute may be stored as a data element sequence */ else if (attr[i] && attr[i + 1] && (strcmp(attr[i], "type") == 0) && (strcmp(attr[i + 1], "DES") == 0)) { /* Set the data element sequence header */ strcpy(search_struct->attrlist + search_struct->attrlist_index, S_DES_HDR1); search_struct->attrlist_index += strlen(S_DES_HDR0) + 1; } /* If we have found a parameter we just insert it into the list */ else if (strncmp(attr[i], "Parameter", 9) == 0) { strcpy(search_struct->attrlist + search_struct->attrlist_index, attr[i + 1]); search_struct->attrlist_index += strlen(attr[i + 1]) + 1; } else { fprintf(stderr, "Unexpected behavior in database when searching for attributes\n"); } } } /* This is when we found a data element sequence, we here browses through all the attributes in the sequence and copies them into our list */ else if (search_struct->attr2get > 0) { search_struct->attr2get--; if (attr[0] && attr[1] && (strcmp(attr[0], "type") == 0) && (strcmp(attr[1], "DES") == 0)) { /* Set the data element sequence header */ strcpy(search_struct->attrlist + search_struct->attrlist_index, S_DES_HDR1); search_struct->attrlist_index += strlen(S_DES_HDR1) + 1; } /* Copy the first attribute */ strcpy(search_struct->attrlist + search_struct->attrlist_index, el); search_struct->attrlist_index += strlen(el) + 1; /* Copy the rest of the attributes */ for (i = 0; attr[i]; i += 2) { strcpy(search_struct->attrlist + search_struct->attrlist_index, attr[i + 1]); search_struct->attrlist_index += strlen(attr[i + 1]) + 1; } /* The length field in the data element sequence will be filled in, in the function get_values */ } }}voidget_attribute_list_end(void *data, const char *el){ sdp_attribute_search *search_hdl = (sdp_attribute_search*) data; int i; char tmp[3]; /* If we found an end tag for the service class we decrease a counter so we can se whether it was the last end tag for the service class or not */ if (strcmp(el, search_hdl->service_class) == 0) { S_FNC("Found %s", el); search_hdl->service_class_found--; } /* If we have found the attribute name end tag, there are no more attributes to find */ else if ((strcmp(el, search_hdl->attribute_name) == 0) && (search_hdl->service_class_found)) { search_hdl->attribute_name_found = 0; } for (i = 0; i < 2; i++) { if (search_hdl->set_des_len[i]) { sprintf(tmp, "%02x", search_hdl->des_len[i]); memcpy(search_hdl->attrlist + search_hdl->des_len_pos[i], tmp, 2); search_hdl->set_des_len[i] = 0; } }}voidget_attribute_char_data(void *userData, const XML_Char *s, int len){ sdp_attribute_search *search_hdl = (sdp_attribute_search*) userData; int i = 0; if (len <= 0) { return; } while (i < len && !FIRST_VALID_CHAR(s[i])) { i++; } if (i == len) { return; } if ((search_hdl->service_class_found) && (search_hdl->attribute_name_found)) { /* We set the length field of the string, now we set it to zero, since we will set it to its correct value later */ sprintf(search_hdl->attrlist + search_hdl->attrlist_index, "0x25"); search_hdl->attrlist_index += 4; /* Stor the length field so we can set the length afterwards */ search_hdl->des_len_pos[0] = search_hdl->attrlist_index; search_hdl->attrlist_index += 2; search_hdl->des_len[0] = 0; search_hdl->set_des_len[0] = 1; for (i = 0; i < len; i++) { /* We stor the ascii value of each character in two bytes */ sprintf(search_hdl->attrlist + search_hdl->attrlist_index, "%01x%01x" , s[i] / 16, s[i] % 16); search_hdl->attrlist_index += 2; search_hdl->des_len[0]++; } search_hdl->attrlist[search_hdl->attrlist_index++] = '\0'; }}/* This function search the xml file for the one of tag, attr or val that is set to NULL. If more than one is set to NULL the result will be unpredicable */char*get_from_xml(int fd, char *tag, char *attr, unsigned char *val){#define TAG 0#define ATTR 1#define VAL 2 XML_Parser p; sdp_search_handler search_hdl; int set_value = -1; p = XML_ParserCreate(NULL); XML_SetElementHandler(p, get_start, get_end); XML_SetUserData(p, &search_hdl); search_hdl.search_name = tag; search_hdl.search_attr = attr; search_hdl.search_val = val; if (!tag) { S_FNC("Looking for tag"); set_value = TAG; } if (!attr) { if (set_value != -1) { fprintf(stderr, __FUNCTION__ ": Error more than one attribute == NULL\n"); return NULL; } S_FNC("Looking for attribute"); set_value = ATTR; } if (!val) { if (set_value != -1) { fprintf(stderr, __FUNCTION__ ": Error more than one attribute == NULL\n"); return NULL; } S_FNC("Looking for value"); set_value = VAL; } start_xml_parser(p, fd); XML_ParserFree(p); switch (set_value) { case TAG: return search_hdl.search_name; case ATTR: return search_hdl.search_attr; case VAL: return search_hdl.search_val; default: return NULL; } #undef TAG#undef ATTR#undef VAl}voidget_start(void *data, const char *el, const char **attr){ int i, m_size; sdp_search_handler *search_hdl = data; if (search_hdl->search_attr == NULL) { if (strcmp(el, search_hdl->search_name) == 0) { S_FNC("Found %s", el); for (i = 0; attr[i]; i += 2) { if (strcmp(attr[i + 1], search_hdl->search_val) == 0) { S_FNC("Found %s", attr[i]); m_size = strlen(attr[i]) + 1; search_hdl->search_attr = malloc(m_size); D_MEM("---> malloc%d %d bytes at 0x%8p", malloc_dbg++, m_size, search_hdl->search_attr); if (search_hdl->search_attr) { strcpy(search_hdl->search_attr, attr[i]); } return; } } } } else if (search_hdl->search_val == NULL) { if (strcmp(el, search_hdl->search_name) == 0) { S_FNC("Found %s", el); for (i = 0; attr[i]; i += 2) { if (strcmp(attr[i], search_hdl->search_attr) == 0) { S_FNC("Found %s", attr[i + 1]); m_size = strlen(attr[i + 1]) + 1; search_hdl->search_val = malloc(m_size); D_MEM("---> malloc%d %d bytes at 0x%8p", malloc_dbg++, m_size, search_hdl->search_val); if (search_hdl->search_val) { strcpy(search_hdl->search_val, attr[i + 1]); } return; } } } } else if (search_hdl->search_name == NULL) { for (i = 0; attr[i]; i += 2) { if ((strcmp(search_hdl->search_attr, attr[i]) == 0) && (strcmp(search_hdl->search_val, attr[i + 1]) == 0)) { m_size = strlen(el) + 1; search_hdl->search_name = malloc(m_size); D_MEM("---> malloc%d %d bytes at 0x%8p", malloc_dbg++, m_size, search_hdl->search_name); if (search_hdl->search_name) { strcpy(search_hdl->search_name, el); } return; } } }} voidget_end(void *data, const char *el){}int*get_all_attributes(int fd){ XML_Parser p; unsigned int *attr_lst, i; sdp_search_handler search_hdl; search_hdl.search_name = "AttributeIdentifierCodes"; search_hdl.search_val = NULL; search_hdl.search_attr = NULL; p = XML_ParserCreate(NULL); XML_SetElementHandler(p, get_all_start, get_all_end); XML_SetUserData(p, &search_hdl); XML_UseParserAsHandlerArg(p); /* Start the parser */ start_xml_parser(p, fd); attr_lst = (unsigned int*)search_hdl.search_val; XML_ParserFree(p); /* If we didn't find the service class we return here */ if (!attr_lst) { D_ATTR("Didn't find anything"); return NULL; } for (i = 1; i <= attr_lst[0]; i++) { D_ATTR("Attribute %d: 0x%04x", i , attr_lst[i]); } return attr_lst;}void get_all_start(void *data, const char *el, const char **attr){ int i, attr_cnt, m_size; sdp_search_handler *search_hdl; search_hdl = (sdp_search_handler*) XML_GetUserData((XML_Parser*) data); if (strncmp(el, search_hdl->search_name, strlen(search_hdl->search_name)) == 0) { unsigned int *attributes; S_FNC("Found %s", el); attr_cnt = XML_GetSpecifiedAttributeCount((XML_Parser*) data); /* Since attr_cnt is the count of both the attibutes and the attribute values, we have to divide it by 2 */ attr_cnt /= 2; S_FNC("%d attributes found", attr_cnt); /* Allocate space for all the attribute UUIDs plus the attribute count in the search_output pointer, */ m_size = (attr_cnt + 1) * sizeof *attributes; search_hdl->search_val = malloc(m_size); attributes = (unsigned int *)search_hdl->search_val; D_MEM("---> malloc%d %d bytes at 0x%8p", malloc_dbg++, m_size, attributes); if (!attributes) { set_err(SDP_INSUFFICIENT_RESOURCES); return; } *attributes++ = (unsigned int)attr_cnt; for (i = 0; attr[i]; i += 2) { unsigned int tmp = strtoul(attr[i + 1], NULL, 16); *attributes++ = tmp; S_FNC("Attribute %d found", tmp); } }}void get_all_end(void *data, const char *el){}void browse_database(){}void browse_database_start(void *data, const char *el, const char **attr){}void browse_database_end(void *data, const char *el){}voidhandle_query(database_query_struct *db_hdl){ switch (db_hdl->pkt_type) { case SDP_SERVICESEARCH_REQ: D_REC("Got SDP_SERVICESEARCH_REQ"); handle_service_search_req((service_search_struct*) db_hdl); break; case SDP_SERVICEATTR_REQ: D_REC("Got SDP_SERVICEATTR_REQ"); handle_service_attr_req((service_attr_struct*) db_hdl); break; case SDP_SERVICESEARCHATTR_REQ: D_REC("Got SDP_SERVICESEARCHATTR_REQ"); handle_service_search_attr_req((service_search_attr_struct*) db_hdl); break; default: fprintf(stderr, "Unrecognised packet 0x%02x\n", db_hdl->pkt_type); break; }}/* FIXME: Add features to handle continuation states and multiple service classes */void handle_service_search_req(service_search_struct *db_hdl){ unsigned char rsp_pkt[256]; int rsp_pkt_len; unsigned int *rec_hdl_list; unsigned int rec_hdl_cnt = 0; unsigned int max_rec_cnt; int i; rec_hdl_list = get_all_rec_hdl(db_hdl->service_class_list, db_hdl->service_class_cnt); if (is_err()) { send_error_rsp(&db_hdl->db, get_err()); } if (rec_hdl_list) { while (rec_hdl_list[rec_hdl_cnt] != NO_REC_HDL) { rec_hdl_cnt++; } } D_MISC("Found %d rec handles in database\n", rec_hdl_cnt); /* Calculate how many records we can fit into response */ /* SdpHdrSize[5] + TotSrvCnt[2] + CurSrvRevCnt[2] + possibl ContState[2] => 11 bytes. Each rec hdl is 4 bytes */ max_rec_cnt = MIN(db_hdl->max_rec_cnt, (db_hdl->db.l2cap_mtu - 11)/4); if (rec_hdl_cnt > max_rec_cnt) { D_REC("Only send %d out of %d record handles\n", max_rec_cnt, rec_hdl_cnt);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -