SDP client for myBlueUSB
Dependents: mbed_TANK_Kinect ftusbClass
sdp.cpp@0:7493bf6bb1b9, 2011-04-04 (annotated)
- Committer:
- networker
- Date:
- Mon Apr 04 16:45:20 2011 +0000
- Revision:
- 0:7493bf6bb1b9
- Child:
- 1:70ee392bcfd4
initial revision
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
networker | 0:7493bf6bb1b9 | 1 | #include "mbed.h" |
networker | 0:7493bf6bb1b9 | 2 | #include "Utils.h" |
networker | 0:7493bf6bb1b9 | 3 | #include "hci.h" |
networker | 0:7493bf6bb1b9 | 4 | #include "sdp_data.h" |
networker | 0:7493bf6bb1b9 | 5 | #include "sdp.h" |
networker | 0:7493bf6bb1b9 | 6 | |
networker | 0:7493bf6bb1b9 | 7 | SDPManager SDP; //instance |
networker | 0:7493bf6bb1b9 | 8 | const unsigned char base_uuid[16] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0, 0x07, 0x70, 0, 0x10, 0, 0}; |
networker | 0:7493bf6bb1b9 | 9 | |
networker | 0:7493bf6bb1b9 | 10 | void attribHandler(serv_rec *r) { |
networker | 0:7493bf6bb1b9 | 11 | printf("Service 0x%08X\n", (*r)[0x0000]->asUnsigned()); |
networker | 0:7493bf6bb1b9 | 12 | map<unsigned short, sdp_data*>::iterator it = r->begin(); |
networker | 0:7493bf6bb1b9 | 13 | for (;it != r->end();it++) { |
networker | 0:7493bf6bb1b9 | 14 | printf(" 0x%04X: %s\n", (*it).first, (*it).second->asString()); |
networker | 0:7493bf6bb1b9 | 15 | } |
networker | 0:7493bf6bb1b9 | 16 | } |
networker | 0:7493bf6bb1b9 | 17 | |
networker | 0:7493bf6bb1b9 | 18 | //this function is called when the L2CAP layer receives SDP packets (see SDPManager::Open), userdata is the sdpmanager instance |
networker | 0:7493bf6bb1b9 | 19 | void SDPManager::OnSdpRsp(int socket, SocketState state, const u8* data, int len, void* userData) { |
networker | 0:7493bf6bb1b9 | 20 | printf("\x1B[%dm", 34); |
networker | 0:7493bf6bb1b9 | 21 | printf("OnSdpRsp(socket=%d, state=%d, len=%d)\n", socket, state, len); |
networker | 0:7493bf6bb1b9 | 22 | //printfBytes("Got SDP Response from L2CAP: ", data, len); |
networker | 0:7493bf6bb1b9 | 23 | SDPManager *self = (SDPManager*)userData; |
networker | 0:7493bf6bb1b9 | 24 | if (state != SocketState_Open) |
networker | 0:7493bf6bb1b9 | 25 | return; |
networker | 0:7493bf6bb1b9 | 26 | sdp_data list(sdp_data::SEQUENCE); |
networker | 0:7493bf6bb1b9 | 27 | if (data) |
networker | 0:7493bf6bb1b9 | 28 | self->parseRsp(data, len); |
networker | 0:7493bf6bb1b9 | 29 | if (len==0) { |
networker | 0:7493bf6bb1b9 | 30 | sdp_data root(sdp_data::UUID, 0x1101); |
networker | 0:7493bf6bb1b9 | 31 | sdp_data req(sdp_data::SEQUENCE); |
networker | 0:7493bf6bb1b9 | 32 | req.add_element(&root); |
networker | 0:7493bf6bb1b9 | 33 | self->ServiceSearchRequest(&req, 5); |
networker | 0:7493bf6bb1b9 | 34 | } else if (data[0]==3) { |
networker | 0:7493bf6bb1b9 | 35 | self->index = self->services.begin(); |
networker | 0:7493bf6bb1b9 | 36 | if (self->index != self->services.end()) { |
networker | 0:7493bf6bb1b9 | 37 | unsigned handle = (*self->index).first; |
networker | 0:7493bf6bb1b9 | 38 | //printf("req.: handle %#X\n", handle); |
networker | 0:7493bf6bb1b9 | 39 | sdp_data all(0xffffU,4); |
networker | 0:7493bf6bb1b9 | 40 | list.add_element(&all); |
networker | 0:7493bf6bb1b9 | 41 | self->ServiceAttributeRequest(handle, 100, &list);//0x1001D |
networker | 0:7493bf6bb1b9 | 42 | self->index++; |
networker | 0:7493bf6bb1b9 | 43 | } else printf(" - empty list - \n");//should not happen |
networker | 0:7493bf6bb1b9 | 44 | } else if (data[0]==5) { |
networker | 0:7493bf6bb1b9 | 45 | if (self->index != self->services.end()) { |
networker | 0:7493bf6bb1b9 | 46 | //printf("req.: handle %#X\n", (*self->index).first); |
networker | 0:7493bf6bb1b9 | 47 | self->ServiceAttributeRequest((*self->index).first, 100, &list); |
networker | 0:7493bf6bb1b9 | 48 | self->index++; |
networker | 0:7493bf6bb1b9 | 49 | } else { |
networker | 0:7493bf6bb1b9 | 50 | printf(" - end of list - \n"); |
networker | 0:7493bf6bb1b9 | 51 | Socket_Close(self->sdp_socket); //Note: socket=L2CAP, sdp_socket=SDP !!! |
networker | 0:7493bf6bb1b9 | 52 | } |
networker | 0:7493bf6bb1b9 | 53 | } |
networker | 0:7493bf6bb1b9 | 54 | printf("\x1B[%dm", 0); |
networker | 0:7493bf6bb1b9 | 55 | } |
networker | 0:7493bf6bb1b9 | 56 | |
networker | 0:7493bf6bb1b9 | 57 | //this function is called when the SDP sockets receives data (see HCICallback in TestShell), |
networker | 0:7493bf6bb1b9 | 58 | //currently does not happen because not forwarded from OnSdpRsp, can be used to handle multiple connections |
networker | 0:7493bf6bb1b9 | 59 | void SDPManager::OnSockCallback(int socket, SocketState state, const u8* data, int len, void* userData) { |
networker | 0:7493bf6bb1b9 | 60 | printf("OnSockCallback(socket=%d, state=%d, len=%d)\n", socket, state, len); |
networker | 0:7493bf6bb1b9 | 61 | printfBytes("Got SDP Response from socket: ", data, len); |
networker | 0:7493bf6bb1b9 | 62 | } |
networker | 0:7493bf6bb1b9 | 63 | |
networker | 0:7493bf6bb1b9 | 64 | void SDPManager::errorhandler(unsigned err) {//default error handler |
networker | 0:7493bf6bb1b9 | 65 | switch (err) { |
networker | 0:7493bf6bb1b9 | 66 | case 1: |
networker | 0:7493bf6bb1b9 | 67 | printf("Unsupported version of SDP\n"); |
networker | 0:7493bf6bb1b9 | 68 | break; |
networker | 0:7493bf6bb1b9 | 69 | case 2: |
networker | 0:7493bf6bb1b9 | 70 | printf("Invalid SDP ServiceRecordHandle\n"); |
networker | 0:7493bf6bb1b9 | 71 | break; |
networker | 0:7493bf6bb1b9 | 72 | case 3: |
networker | 0:7493bf6bb1b9 | 73 | printf("SDP syntax error\n"); |
networker | 0:7493bf6bb1b9 | 74 | break; |
networker | 0:7493bf6bb1b9 | 75 | case 4: |
networker | 0:7493bf6bb1b9 | 76 | printf("PDU size was invalid\n"); |
networker | 0:7493bf6bb1b9 | 77 | break; |
networker | 0:7493bf6bb1b9 | 78 | case 5: |
networker | 0:7493bf6bb1b9 | 79 | printf("Continuation state was invalid\n"); |
networker | 0:7493bf6bb1b9 | 80 | break; |
networker | 0:7493bf6bb1b9 | 81 | case 6: |
networker | 0:7493bf6bb1b9 | 82 | printf("SDP server has insufficient resources\n"); |
networker | 0:7493bf6bb1b9 | 83 | break; |
networker | 0:7493bf6bb1b9 | 84 | default: |
networker | 0:7493bf6bb1b9 | 85 | printf("Unknown SDP error code\n"); |
networker | 0:7493bf6bb1b9 | 86 | break; |
networker | 0:7493bf6bb1b9 | 87 | } |
networker | 0:7493bf6bb1b9 | 88 | } |
networker | 0:7493bf6bb1b9 | 89 | |
networker | 0:7493bf6bb1b9 | 90 | int SDPManager::ServiceSearchRequest(sdp_data *sp, unsigned count, unsigned cs) { |
networker | 0:7493bf6bb1b9 | 91 | int parlen = sp->Size() + 3; //no continuation |
networker | 0:7493bf6bb1b9 | 92 | buf[0] = 2; //pdu |
networker | 0:7493bf6bb1b9 | 93 | buf[1] = txid>>8; |
networker | 0:7493bf6bb1b9 | 94 | buf[2] = txid++; |
networker | 0:7493bf6bb1b9 | 95 | buf[4] = parlen; |
networker | 0:7493bf6bb1b9 | 96 | buf[3] = parlen>>8; |
networker | 0:7493bf6bb1b9 | 97 | int p = sp->build(buf+5, 100-10); |
networker | 0:7493bf6bb1b9 | 98 | buf[p+6] = count; |
networker | 0:7493bf6bb1b9 | 99 | buf[p+5] = count>>8; |
networker | 0:7493bf6bb1b9 | 100 | if (cs==0) |
networker | 0:7493bf6bb1b9 | 101 | buf[p+7] = 0; |
networker | 0:7493bf6bb1b9 | 102 | else |
networker | 0:7493bf6bb1b9 | 103 | printf("Continuation not supported\n"); |
networker | 0:7493bf6bb1b9 | 104 | //printfBytes("SDP Send: ", buf, parlen+5); |
networker | 0:7493bf6bb1b9 | 105 | return Socket_Send(_l2cap, l2cap_buf, parlen + 5 + OFFSET); |
networker | 0:7493bf6bb1b9 | 106 | } |
networker | 0:7493bf6bb1b9 | 107 | |
networker | 0:7493bf6bb1b9 | 108 | int SDPManager::ServiceAttributeRequest(unsigned handle, unsigned count, sdp_data* al, unsigned cs) { |
networker | 0:7493bf6bb1b9 | 109 | int parlen = al->Size() + 7; //no continuation |
networker | 0:7493bf6bb1b9 | 110 | buf[0] = 4; //pdu |
networker | 0:7493bf6bb1b9 | 111 | buf[1] = txid>>8; |
networker | 0:7493bf6bb1b9 | 112 | buf[2] = txid++; |
networker | 0:7493bf6bb1b9 | 113 | buf[4] = parlen; |
networker | 0:7493bf6bb1b9 | 114 | buf[3] = parlen>>8; |
networker | 0:7493bf6bb1b9 | 115 | for (int i = 0; i < 4; i++) |
networker | 0:7493bf6bb1b9 | 116 | buf[i+5] = ((char*)&handle)[3-i]; |
networker | 0:7493bf6bb1b9 | 117 | buf[9] = count>>8; |
networker | 0:7493bf6bb1b9 | 118 | buf[10] = count; |
networker | 0:7493bf6bb1b9 | 119 | int p = al->build(buf+11, 100-26); |
networker | 0:7493bf6bb1b9 | 120 | if (cs==0) |
networker | 0:7493bf6bb1b9 | 121 | buf[p+11] = 0; |
networker | 0:7493bf6bb1b9 | 122 | else |
networker | 0:7493bf6bb1b9 | 123 | printf("Continuation not supported\n"); |
networker | 0:7493bf6bb1b9 | 124 | //printfBytes("SDP Send: ", buf, parlen+5); |
networker | 0:7493bf6bb1b9 | 125 | return Socket_Send(_l2cap, l2cap_buf, parlen + 5 + OFFSET); |
networker | 0:7493bf6bb1b9 | 126 | } |
networker | 0:7493bf6bb1b9 | 127 | |
networker | 0:7493bf6bb1b9 | 128 | int SDPManager::ServiceSearchAttributeRequest(sdp_data *sp, unsigned count, sdp_data* al, unsigned cs) { |
networker | 0:7493bf6bb1b9 | 129 | int parlen = sp->Size() + al->Size() + 3; //no continuation (1 byte), count (2 bytes) |
networker | 0:7493bf6bb1b9 | 130 | buf[0] = 6; //pdu |
networker | 0:7493bf6bb1b9 | 131 | buf[1] = txid>>8; |
networker | 0:7493bf6bb1b9 | 132 | buf[2] = txid++; |
networker | 0:7493bf6bb1b9 | 133 | buf[4] = parlen; |
networker | 0:7493bf6bb1b9 | 134 | buf[3] = parlen>>8; |
networker | 0:7493bf6bb1b9 | 135 | int p = sp->build(buf+5, 30); |
networker | 0:7493bf6bb1b9 | 136 | buf[p+6] = count; |
networker | 0:7493bf6bb1b9 | 137 | buf[p+5] = count>>8; |
networker | 0:7493bf6bb1b9 | 138 | p += al->build(buf+11, 100-38); |
networker | 0:7493bf6bb1b9 | 139 | if (cs==0) |
networker | 0:7493bf6bb1b9 | 140 | buf[p+7] = 0; |
networker | 0:7493bf6bb1b9 | 141 | else |
networker | 0:7493bf6bb1b9 | 142 | printf("Continuation not supported\n"); |
networker | 0:7493bf6bb1b9 | 143 | //printfBytes("SDP Send: ", buf, parlen+5); |
networker | 0:7493bf6bb1b9 | 144 | return Socket_Send(_l2cap, l2cap_buf, parlen + 5 + OFFSET); |
networker | 0:7493bf6bb1b9 | 145 | } |
networker | 0:7493bf6bb1b9 | 146 | |
networker | 0:7493bf6bb1b9 | 147 | unsigned SDPManager::getval(const unsigned char *p, int n) { |
networker | 0:7493bf6bb1b9 | 148 | unsigned ret = 0; |
networker | 0:7493bf6bb1b9 | 149 | for (int i = 0; i < n; i++) |
networker | 0:7493bf6bb1b9 | 150 | ret = (ret<<8) + (unsigned)p[i]; |
networker | 0:7493bf6bb1b9 | 151 | return ret; |
networker | 0:7493bf6bb1b9 | 152 | } |
networker | 0:7493bf6bb1b9 | 153 | |
networker | 0:7493bf6bb1b9 | 154 | unsigned SDPManager::length(const unsigned char *el, unsigned &p) { |
networker | 0:7493bf6bb1b9 | 155 | unsigned len = 0; |
networker | 0:7493bf6bb1b9 | 156 | switch (el[p++] & 7) {//length |
networker | 0:7493bf6bb1b9 | 157 | case 0: |
networker | 0:7493bf6bb1b9 | 158 | len = 1; |
networker | 0:7493bf6bb1b9 | 159 | break; |
networker | 0:7493bf6bb1b9 | 160 | case 1: |
networker | 0:7493bf6bb1b9 | 161 | len = 2; |
networker | 0:7493bf6bb1b9 | 162 | break; |
networker | 0:7493bf6bb1b9 | 163 | case 2: |
networker | 0:7493bf6bb1b9 | 164 | len = 4; |
networker | 0:7493bf6bb1b9 | 165 | break; |
networker | 0:7493bf6bb1b9 | 166 | case 3: |
networker | 0:7493bf6bb1b9 | 167 | len = 8; |
networker | 0:7493bf6bb1b9 | 168 | break; |
networker | 0:7493bf6bb1b9 | 169 | case 4: |
networker | 0:7493bf6bb1b9 | 170 | len = 16; |
networker | 0:7493bf6bb1b9 | 171 | break; |
networker | 0:7493bf6bb1b9 | 172 | case 7://4bytes |
networker | 0:7493bf6bb1b9 | 173 | len= el[p++]<<24; |
networker | 0:7493bf6bb1b9 | 174 | len += el[p++]<<16; |
networker | 0:7493bf6bb1b9 | 175 | case 6://2bytes |
networker | 0:7493bf6bb1b9 | 176 | len += el[p++]<<8; |
networker | 0:7493bf6bb1b9 | 177 | case 5://1byte |
networker | 0:7493bf6bb1b9 | 178 | len += el[p++]; |
networker | 0:7493bf6bb1b9 | 179 | break; |
networker | 0:7493bf6bb1b9 | 180 | } |
networker | 0:7493bf6bb1b9 | 181 | return len; |
networker | 0:7493bf6bb1b9 | 182 | } |
networker | 0:7493bf6bb1b9 | 183 | |
networker | 0:7493bf6bb1b9 | 184 | extern "C" void HardFault_Handler() { printf("Hard Fault!\n"); while(1); } |
networker | 0:7493bf6bb1b9 | 185 | |
networker | 0:7493bf6bb1b9 | 186 | |
networker | 0:7493bf6bb1b9 | 187 | unsigned SDPManager::parse (const unsigned char *el, unsigned count, sdp_data* &result, serv_rec* &record) { |
networker | 0:7493bf6bb1b9 | 188 | unsigned p = 0; |
networker | 0:7493bf6bb1b9 | 189 | unsigned len = length(el, p); |
networker | 0:7493bf6bb1b9 | 190 | int end = p+len;//end is the index of the item just after the sequence |
networker | 0:7493bf6bb1b9 | 191 | sdp_data *item = 0; |
networker | 0:7493bf6bb1b9 | 192 | switch (el[0]>>3) {//type |
networker | 0:7493bf6bb1b9 | 193 | case sdp_data::NULL_: |
networker | 0:7493bf6bb1b9 | 194 | item = new sdp_data(); |
networker | 0:7493bf6bb1b9 | 195 | break; |
networker | 0:7493bf6bb1b9 | 196 | case sdp_data::UNSIGNED: |
networker | 0:7493bf6bb1b9 | 197 | item = new sdp_data((unsigned)getval(el+p, len), len); |
networker | 0:7493bf6bb1b9 | 198 | break; |
networker | 0:7493bf6bb1b9 | 199 | case sdp_data::SIGNED: |
networker | 0:7493bf6bb1b9 | 200 | item = new sdp_data((int)getval(el+p, len), len); |
networker | 0:7493bf6bb1b9 | 201 | break; |
networker | 0:7493bf6bb1b9 | 202 | case sdp_data::UUID: |
networker | 0:7493bf6bb1b9 | 203 | if (len==16) { |
networker | 0:7493bf6bb1b9 | 204 | char rev[16]; |
networker | 0:7493bf6bb1b9 | 205 | for (int i = 0; i < 16; i++) |
networker | 0:7493bf6bb1b9 | 206 | rev[i] = el[p+15-i]; |
networker | 0:7493bf6bb1b9 | 207 | item = new sdp_data(sdp_data::UUID, rev, len); |
networker | 0:7493bf6bb1b9 | 208 | } else |
networker | 0:7493bf6bb1b9 | 209 | item = new sdp_data(sdp_data::UUID, getval(el+p, len), len); |
networker | 0:7493bf6bb1b9 | 210 | break; |
networker | 0:7493bf6bb1b9 | 211 | case sdp_data::STRING: |
networker | 0:7493bf6bb1b9 | 212 | item = new sdp_data((char*)el+p, len); |
networker | 0:7493bf6bb1b9 | 213 | break; |
networker | 0:7493bf6bb1b9 | 214 | case sdp_data::BOOL: |
networker | 0:7493bf6bb1b9 | 215 | item = new sdp_data((bool)getval(el+p, len), len); |
networker | 0:7493bf6bb1b9 | 216 | break; |
networker | 0:7493bf6bb1b9 | 217 | case sdp_data::SEQUENCE: |
networker | 0:7493bf6bb1b9 | 218 | item = new sdp_data(sdp_data::SEQUENCE); |
networker | 0:7493bf6bb1b9 | 219 | goto skip; |
networker | 0:7493bf6bb1b9 | 220 | case sdp_data::ALTERNATIVE: |
networker | 0:7493bf6bb1b9 | 221 | item = new sdp_data(sdp_data::ALTERNATIVE); |
networker | 0:7493bf6bb1b9 | 222 | skip: {//p points just after the length indicator, hence at the first item IN the sequence |
networker | 0:7493bf6bb1b9 | 223 | // printf("SEQ%d{%p ", len, item); |
networker | 0:7493bf6bb1b9 | 224 | int n = 0; |
networker | 0:7493bf6bb1b9 | 225 | unsigned short key; |
networker | 0:7493bf6bb1b9 | 226 | serv_rec *dummy = 0; |
networker | 0:7493bf6bb1b9 | 227 | while (p < end) { |
networker | 0:7493bf6bb1b9 | 228 | sdp_data *elem = 0; |
networker | 0:7493bf6bb1b9 | 229 | p += parse(el + p, len-p, elem, dummy);//parse each element in the sequence, the second arg is as yet unused |
networker | 0:7493bf6bb1b9 | 230 | item->add_element(elem); |
networker | 0:7493bf6bb1b9 | 231 | if (record) { |
networker | 0:7493bf6bb1b9 | 232 | if (n & 1) { //value |
networker | 0:7493bf6bb1b9 | 233 | record->insert(pair<unsigned short, sdp_data*>(key, elem)); |
networker | 0:7493bf6bb1b9 | 234 | } else //key |
networker | 0:7493bf6bb1b9 | 235 | key = elem->asUnsigned(); |
networker | 0:7493bf6bb1b9 | 236 | n++; |
networker | 0:7493bf6bb1b9 | 237 | } |
networker | 0:7493bf6bb1b9 | 238 | } |
networker | 0:7493bf6bb1b9 | 239 | } |
networker | 0:7493bf6bb1b9 | 240 | // printf("}\n"); |
networker | 0:7493bf6bb1b9 | 241 | break; |
networker | 0:7493bf6bb1b9 | 242 | case 8: |
networker | 0:7493bf6bb1b9 | 243 | item = new sdp_data(sdp_data::URL, (char*)el+p, len); |
networker | 0:7493bf6bb1b9 | 244 | break; |
networker | 0:7493bf6bb1b9 | 245 | default: |
networker | 0:7493bf6bb1b9 | 246 | printf("Parse: Unknown type %d, len=%d (code=%#02X)\n", el[0]>>3, len, el[0]); |
networker | 0:7493bf6bb1b9 | 247 | } |
networker | 0:7493bf6bb1b9 | 248 | result = item; |
networker | 0:7493bf6bb1b9 | 249 | return end; |
networker | 0:7493bf6bb1b9 | 250 | } |
networker | 0:7493bf6bb1b9 | 251 | |
networker | 0:7493bf6bb1b9 | 252 | int SDPManager::parseRsp(const unsigned char*rsp, int len) { |
networker | 0:7493bf6bb1b9 | 253 | //unsigned tid = rsp[2] + ((unsigned)rsp[1]<<8); |
networker | 0:7493bf6bb1b9 | 254 | unsigned parlen = rsp[4] + ((unsigned)rsp[3]<<8); |
networker | 0:7493bf6bb1b9 | 255 | // printf("ParseRsp: tid=%04X, parlen=%d ", tid, parlen); |
networker | 0:7493bf6bb1b9 | 256 | unsigned cont = 0; |
networker | 0:7493bf6bb1b9 | 257 | switch (rsp[0]) { |
networker | 0:7493bf6bb1b9 | 258 | case 1: {//errorRsp |
networker | 0:7493bf6bb1b9 | 259 | unsigned errorcode = rsp[6] + ((unsigned)rsp[5]<<8); |
networker | 0:7493bf6bb1b9 | 260 | if (parlen > 2) { |
networker | 0:7493bf6bb1b9 | 261 | printf("ErrorInfo (%d bytes) for error %d is available\n", parlen-2, errorcode); |
networker | 0:7493bf6bb1b9 | 262 | } |
networker | 0:7493bf6bb1b9 | 263 | if (ErrorResponse) |
networker | 0:7493bf6bb1b9 | 264 | ErrorResponse(errorcode); |
networker | 0:7493bf6bb1b9 | 265 | return errorcode; |
networker | 0:7493bf6bb1b9 | 266 | } |
networker | 0:7493bf6bb1b9 | 267 | //break; |
networker | 0:7493bf6bb1b9 | 268 | case 3: { //servicesearchRsp |
networker | 0:7493bf6bb1b9 | 269 | //unsigned total = rsp[6] + ((unsigned)rsp[5]<<8); |
networker | 0:7493bf6bb1b9 | 270 | unsigned current = rsp[8] + ((unsigned)rsp[7]<<8); |
networker | 0:7493bf6bb1b9 | 271 | cont = rsp[9+4*current]; |
networker | 0:7493bf6bb1b9 | 272 | // printf("total=%d, current=%d, cont=%d\n", total, current, cont); |
networker | 0:7493bf6bb1b9 | 273 | if (cont) break; |
networker | 0:7493bf6bb1b9 | 274 | //linear list of 32bit service-handles |
networker | 0:7493bf6bb1b9 | 275 | for (int i = 0; i < current; i++) { |
networker | 0:7493bf6bb1b9 | 276 | unsigned result = 0; |
networker | 0:7493bf6bb1b9 | 277 | for (int j = 0; j< 4; j++) |
networker | 0:7493bf6bb1b9 | 278 | result = (result<<8) + rsp[9 + 4*i + j]; |
networker | 0:7493bf6bb1b9 | 279 | // printf("SDP Search handle %08X\n", result); |
networker | 0:7493bf6bb1b9 | 280 | services.insert(pair<unsigned, serv_rec*>(result, 0)); |
networker | 0:7493bf6bb1b9 | 281 | } |
networker | 0:7493bf6bb1b9 | 282 | if (ServiceSearchResponse) |
networker | 0:7493bf6bb1b9 | 283 | ServiceSearchResponse(); |
networker | 0:7493bf6bb1b9 | 284 | } |
networker | 0:7493bf6bb1b9 | 285 | break; |
networker | 0:7493bf6bb1b9 | 286 | case 5: { //serviceattributeRsp |
networker | 0:7493bf6bb1b9 | 287 | if (tree) delete tree; |
networker | 0:7493bf6bb1b9 | 288 | unsigned count = rsp[6] + ((unsigned)rsp[5]<<8); |
networker | 0:7493bf6bb1b9 | 289 | cont = rsp[7+count]; |
networker | 0:7493bf6bb1b9 | 290 | if (cont) |
networker | 0:7493bf6bb1b9 | 291 | break; |
networker | 0:7493bf6bb1b9 | 292 | // printf("pos=%d, count=%d parsing...\n", 7, count); |
networker | 0:7493bf6bb1b9 | 293 | serv_rec *serv = new serv_rec; |
networker | 0:7493bf6bb1b9 | 294 | unsigned p = parse(rsp+7, count, tree, serv); |
networker | 0:7493bf6bb1b9 | 295 | unsigned key = (*serv)[0]->asUnsigned(); |
networker | 0:7493bf6bb1b9 | 296 | services[key] = serv; |
networker | 0:7493bf6bb1b9 | 297 | // printf("...parsing done, pos=%d, cont=%d\n", p, cont); |
networker | 0:7493bf6bb1b9 | 298 | if (ServiceAttributeResponse) |
networker | 0:7493bf6bb1b9 | 299 | ServiceAttributeResponse(serv); |
networker | 0:7493bf6bb1b9 | 300 | } |
networker | 0:7493bf6bb1b9 | 301 | break; |
networker | 0:7493bf6bb1b9 | 302 | case 7: { //servicesearchattributeRsp |
networker | 0:7493bf6bb1b9 | 303 | if (tree) delete tree; |
networker | 0:7493bf6bb1b9 | 304 | unsigned count = rsp[6] + ((unsigned)rsp[5]<<8); |
networker | 0:7493bf6bb1b9 | 305 | cont = rsp[7+count]; |
networker | 0:7493bf6bb1b9 | 306 | if (cont) |
networker | 0:7493bf6bb1b9 | 307 | break; |
networker | 0:7493bf6bb1b9 | 308 | unsigned pos = 7; |
networker | 0:7493bf6bb1b9 | 309 | while (rsp[pos]>>3 == sdp_data::SEQUENCE) { |
networker | 0:7493bf6bb1b9 | 310 | unsigned len = length(rsp, pos); |
networker | 0:7493bf6bb1b9 | 311 | printf("pos=%d, count=%d, parsing...\n", pos, len); |
networker | 0:7493bf6bb1b9 | 312 | serv_rec *serv = new serv_rec; |
networker | 0:7493bf6bb1b9 | 313 | pos = parse(rsp+pos, len, tree, serv); |
networker | 0:7493bf6bb1b9 | 314 | unsigned key = (*serv)[0]->asUnsigned(); |
networker | 0:7493bf6bb1b9 | 315 | services[key] = serv; |
networker | 0:7493bf6bb1b9 | 316 | } |
networker | 0:7493bf6bb1b9 | 317 | printf("...parsing done, pos=%d\n", pos); |
networker | 0:7493bf6bb1b9 | 318 | if (ServiceSearchAttributeResponse) |
networker | 0:7493bf6bb1b9 | 319 | ServiceSearchAttributeResponse(); |
networker | 0:7493bf6bb1b9 | 320 | } |
networker | 0:7493bf6bb1b9 | 321 | break; |
networker | 0:7493bf6bb1b9 | 322 | default: |
networker | 0:7493bf6bb1b9 | 323 | printf("Unknown SDP response type %02X\n", rsp[0]); |
networker | 0:7493bf6bb1b9 | 324 | break; |
networker | 0:7493bf6bb1b9 | 325 | } |
networker | 0:7493bf6bb1b9 | 326 | if (cont) |
networker | 0:7493bf6bb1b9 | 327 | printf("Continuation not supported (yet)\n"); |
networker | 0:7493bf6bb1b9 | 328 | return 0; |
networker | 0:7493bf6bb1b9 | 329 | } |