comparison src/protocols/oscar/family_locate.c @ 13239:f260d319bbbc

[gaim-migrate @ 15605] Renaming a bunch of structs and typedefs to use the same naming scheme as the rest of Gaim committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 12 Feb 2006 16:02:05 +0000
parents f2431a7e33aa
children 87a7c3077c19
comparison
equal deleted inserted replaced
13238:1e855032d7bc 13239:f260d319bbbc
223 * Add the userinfo to our linked list. If we already have userinfo 223 * Add the userinfo to our linked list. If we already have userinfo
224 * for this buddy, then just overwrite parts of the old data. 224 * for this buddy, then just overwrite parts of the old data.
225 * 225 *
226 * @param userinfo Contains the new information for the buddy. 226 * @param userinfo Contains the new information for the buddy.
227 */ 227 */
228 static void aim_locate_adduserinfo(aim_session_t *sess, aim_userinfo_t *userinfo) { 228 static void aim_locate_adduserinfo(OscarSession *sess, aim_userinfo_t *userinfo) {
229 aim_userinfo_t *cur; 229 aim_userinfo_t *cur;
230 aim_conn_t *conn; 230 OscarConnection *conn;
231 aim_rxcallback_t userfunc; 231 aim_rxcallback_t userfunc;
232 232
233 cur = aim_locate_finduserinfo(sess, userinfo->sn); 233 cur = aim_locate_finduserinfo(sess, userinfo->sn);
234 234
235 if (cur == NULL) { 235 if (cur == NULL) {
310 conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE); 310 conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE);
311 if ((userfunc = aim_callhandler(sess, conn, OSCAR_FAMILY_LOCATE, OSCAR_SUBTYPE_LOCATE_GOTINFOBLOCK))) 311 if ((userfunc = aim_callhandler(sess, conn, OSCAR_FAMILY_LOCATE, OSCAR_SUBTYPE_LOCATE_GOTINFOBLOCK)))
312 userfunc(sess, NULL, cur); 312 userfunc(sess, NULL, cur);
313 } 313 }
314 314
315 faim_export void aim_locate_dorequest(aim_session_t *sess) { 315 faim_export void aim_locate_dorequest(OscarSession *sess) {
316 struct userinfo_node *cur = sess->locate.torequest; 316 struct userinfo_node *cur = sess->locate.torequest;
317 317
318 if (cur == NULL) 318 if (cur == NULL)
319 return; 319 return;
320 320
337 * @param sess The aim session. 337 * @param sess The aim session.
338 * @param sn Screen name of the info we just received. 338 * @param sn Screen name of the info we just received.
339 * @return True if the request was explicit (client requested the info), 339 * @return True if the request was explicit (client requested the info),
340 * false if the request was implicit (libfaim request the info). 340 * false if the request was implicit (libfaim request the info).
341 */ 341 */
342 static int aim_locate_gotuserinfo(aim_session_t *sess, const char *sn) { 342 static int aim_locate_gotuserinfo(OscarSession *sess, const char *sn) {
343 struct userinfo_node *cur, *del; 343 struct userinfo_node *cur, *del;
344 int was_explicit = TRUE; 344 int was_explicit = TRUE;
345 345
346 while ((sess->locate.requested != NULL) && (aim_sncmp(sn, sess->locate.requested->sn) == 0)) { 346 while ((sess->locate.requested != NULL) && (aim_sncmp(sn, sess->locate.requested->sn) == 0)) {
347 del = sess->locate.requested; 347 del = sess->locate.requested;
362 } else 362 } else
363 cur = cur->next; 363 cur = cur->next;
364 } 364 }
365 365
366 if (!was_explicit) { 366 if (!was_explicit) {
367 aim_conn_t *conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE); 367 OscarConnection *conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE);
368 aim_rxcallback_t userfunc; 368 aim_rxcallback_t userfunc;
369 369
370 sess->locate.waiting_for_response = FALSE; 370 sess->locate.waiting_for_response = FALSE;
371 371
372 if ((userfunc = aim_callhandler(sess, conn, OSCAR_FAMILY_LOCATE, OSCAR_SUBTYPE_LOCATE_REQUESTINFOTIMEOUT))) 372 if ((userfunc = aim_callhandler(sess, conn, OSCAR_FAMILY_LOCATE, OSCAR_SUBTYPE_LOCATE_REQUESTINFOTIMEOUT)))
376 } 376 }
377 377
378 return was_explicit; 378 return was_explicit;
379 } 379 }
380 380
381 faim_internal void aim_locate_requestuserinfo(aim_session_t *sess, const char *sn) { 381 faim_internal void aim_locate_requestuserinfo(OscarSession *sess, const char *sn) {
382 struct userinfo_node *cur; 382 struct userinfo_node *cur;
383 383
384 /* Make sure we aren't already requesting info for this buddy */ 384 /* Make sure we aren't already requesting info for this buddy */
385 cur = sess->locate.torequest; 385 cur = sess->locate.torequest;
386 while (cur != NULL) { 386 while (cur != NULL) {
397 397
398 /* Actually request some info up in this piece */ 398 /* Actually request some info up in this piece */
399 aim_locate_dorequest(sess); 399 aim_locate_dorequest(sess);
400 } 400 }
401 401
402 faim_export aim_userinfo_t *aim_locate_finduserinfo(aim_session_t *sess, const char *sn) { 402 faim_export aim_userinfo_t *aim_locate_finduserinfo(OscarSession *sess, const char *sn) {
403 aim_userinfo_t *cur = NULL; 403 aim_userinfo_t *cur = NULL;
404 404
405 if (sn == NULL) 405 if (sn == NULL)
406 return NULL; 406 return NULL;
407 407
414 } 414 }
415 415
416 return NULL; 416 return NULL;
417 } 417 }
418 418
419 faim_internal guint32 aim_locate_getcaps(aim_session_t *sess, aim_bstream_t *bs, int len) 419 faim_internal guint32 aim_locate_getcaps(OscarSession *sess, ByteStream *bs, int len)
420 { 420 {
421 guint32 flags = 0; 421 guint32 flags = 0;
422 int offset; 422 int offset;
423 423
424 for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x10) { 424 for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x10) {
448 } 448 }
449 449
450 return flags; 450 return flags;
451 } 451 }
452 452
453 faim_internal guint32 aim_locate_getcaps_short(aim_session_t *sess, aim_bstream_t *bs, int len) 453 faim_internal guint32 aim_locate_getcaps_short(OscarSession *sess, ByteStream *bs, int len)
454 { 454 {
455 guint32 flags = 0; 455 guint32 flags = 0;
456 int offset; 456 int offset;
457 457
458 for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x02) { 458 for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x02) {
476 } 476 }
477 477
478 return flags; 478 return flags;
479 } 479 }
480 480
481 faim_internal int aimbs_putcaps(aim_bstream_t *bs, guint32 caps) 481 faim_internal int aimbs_putcaps(ByteStream *bs, guint32 caps)
482 { 482 {
483 int i; 483 int i;
484 484
485 if (!bs) 485 if (!bs)
486 return -EINVAL; 486 return -EINVAL;
496 } 496 }
497 497
498 return 0; 498 return 0;
499 } 499 }
500 500
501 static void dumptlv(aim_session_t *sess, guint16 type, aim_bstream_t *bs, guint8 len) 501 static void dumptlv(OscarSession *sess, guint16 type, ByteStream *bs, guint8 len)
502 { 502 {
503 int i; 503 int i;
504 504
505 if (!sess || !bs || !len) 505 if (!sess || !bs || !len)
506 return; 506 return;
534 534
535 /* 535 /*
536 * AIM is fairly regular about providing user info. This is a generic 536 * AIM is fairly regular about providing user info. This is a generic
537 * routine to extract it in its standard form. 537 * routine to extract it in its standard form.
538 */ 538 */
539 faim_internal int aim_info_extract(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *outinfo) 539 faim_internal int aim_info_extract(OscarSession *sess, ByteStream *bs, aim_userinfo_t *outinfo)
540 { 540 {
541 int curtlv, tlvcnt; 541 int curtlv, tlvcnt;
542 guint8 snlen; 542 guint8 snlen;
543 543
544 if (!bs || !outinfo) 544 if (!bs || !outinfo)
859 } 859 }
860 860
861 /* 861 /*
862 * Inverse of aim_info_extract() 862 * Inverse of aim_info_extract()
863 */ 863 */
864 faim_internal int aim_putuserinfo(aim_bstream_t *bs, aim_userinfo_t *info) 864 faim_internal int aim_putuserinfo(ByteStream *bs, aim_userinfo_t *info)
865 { 865 {
866 aim_tlvlist_t *tlvlist = NULL; 866 aim_tlvlist_t *tlvlist = NULL;
867 867
868 if (!bs || !info) 868 if (!bs || !info)
869 return -EINVAL; 869 return -EINVAL;
906 } 906 }
907 907
908 /* 908 /*
909 * Subtype 0x0001 909 * Subtype 0x0001
910 */ 910 */
911 static int error(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 911 static int error(OscarSession *sess, aim_module_t *mod, FlapFrame *rx, aim_modsnac_t *snac, ByteStream *bs)
912 { 912 {
913 int ret = 0; 913 int ret = 0;
914 aim_rxcallback_t userfunc; 914 aim_rxcallback_t userfunc;
915 aim_snac_t *snac2; 915 aim_snac_t *snac2;
916 guint16 reason; 916 guint16 reason;
955 * Subtype 0x0002 955 * Subtype 0x0002
956 * 956 *
957 * Request Location services rights. 957 * Request Location services rights.
958 * 958 *
959 */ 959 */
960 faim_export int aim_locate_reqrights(aim_session_t *sess) 960 faim_export int aim_locate_reqrights(OscarSession *sess)
961 { 961 {
962 aim_conn_t *conn; 962 OscarConnection *conn;
963 963
964 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE))) 964 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)))
965 return -EINVAL; 965 return -EINVAL;
966 966
967 return aim_genericreq_n_snacid(sess, conn, OSCAR_FAMILY_LOCATE, OSCAR_SUBTYPE_LOCATE_REQRIGHTS); 967 return aim_genericreq_n_snacid(sess, conn, OSCAR_FAMILY_LOCATE, OSCAR_SUBTYPE_LOCATE_REQRIGHTS);
974 * t(0001) - short containing max profile length (value = 1024) 974 * t(0001) - short containing max profile length (value = 1024)
975 * t(0002) - short - unknown (value = 16) [max MIME type length?] 975 * t(0002) - short - unknown (value = 16) [max MIME type length?]
976 * t(0003) - short - unknown (value = 10) 976 * t(0003) - short - unknown (value = 10)
977 * t(0004) - short - unknown (value = 2048) [ICQ only?] 977 * t(0004) - short - unknown (value = 2048) [ICQ only?]
978 */ 978 */
979 static int rights(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 979 static int rights(OscarSession *sess, aim_module_t *mod, FlapFrame *rx, aim_modsnac_t *snac, ByteStream *bs)
980 { 980 {
981 aim_tlvlist_t *tlvlist; 981 aim_tlvlist_t *tlvlist;
982 aim_rxcallback_t userfunc; 982 aim_rxcallback_t userfunc;
983 int ret = 0; 983 int ret = 0;
984 guint16 maxsiglen = 0; 984 guint16 maxsiglen = 0;
1014 * To get the previous behavior of awaymsg == "" un-setting the away 1014 * To get the previous behavior of awaymsg == "" un-setting the away
1015 * message, set awaymsg non-NULL and awaymsg_len to 0 (this is the 1015 * message, set awaymsg non-NULL and awaymsg_len to 0 (this is the
1016 * obvious equivalent). 1016 * obvious equivalent).
1017 * 1017 *
1018 */ 1018 */
1019 faim_export int aim_locate_setprofile(aim_session_t *sess, 1019 faim_export int aim_locate_setprofile(OscarSession *sess,
1020 const char *profile_encoding, const gchar *profile, const int profile_len, 1020 const char *profile_encoding, const gchar *profile, const int profile_len,
1021 const char *awaymsg_encoding, const gchar *awaymsg, const int awaymsg_len) 1021 const char *awaymsg_encoding, const gchar *awaymsg, const int awaymsg_len)
1022 { 1022 {
1023 aim_conn_t *conn; 1023 OscarConnection *conn;
1024 aim_frame_t *fr; 1024 FlapFrame *fr;
1025 aim_snacid_t snacid; 1025 aim_snacid_t snacid;
1026 aim_tlvlist_t *tl = NULL; 1026 aim_tlvlist_t *tl = NULL;
1027 char *encoding; 1027 char *encoding;
1028 static const char defencoding[] = {"text/aolrtf; charset=\"%s\""}; 1028 static const char defencoding[] = {"text/aolrtf; charset=\"%s\""};
1029 1029
1087 } 1087 }
1088 1088
1089 /* 1089 /*
1090 * Subtype 0x0004 - Set your client's capabilities. 1090 * Subtype 0x0004 - Set your client's capabilities.
1091 */ 1091 */
1092 faim_export int aim_locate_setcaps(aim_session_t *sess, guint32 caps) 1092 faim_export int aim_locate_setcaps(OscarSession *sess, guint32 caps)
1093 { 1093 {
1094 aim_conn_t *conn; 1094 OscarConnection *conn;
1095 aim_frame_t *fr; 1095 FlapFrame *fr;
1096 aim_snacid_t snacid; 1096 aim_snacid_t snacid;
1097 aim_tlvlist_t *tl = NULL; 1097 aim_tlvlist_t *tl = NULL;
1098 1098
1099 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE))) 1099 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)))
1100 return -EINVAL; 1100 return -EINVAL;
1122 * @param infotype The type of info you wish to request. 1122 * @param infotype The type of info you wish to request.
1123 * 0x0001 - Info/profile 1123 * 0x0001 - Info/profile
1124 * 0x0003 - Away message 1124 * 0x0003 - Away message
1125 * 0x0004 - Capabilities 1125 * 0x0004 - Capabilities
1126 */ 1126 */
1127 faim_export int aim_locate_getinfo(aim_session_t *sess, const char *sn, guint16 infotype) 1127 faim_export int aim_locate_getinfo(OscarSession *sess, const char *sn, guint16 infotype)
1128 { 1128 {
1129 aim_conn_t *conn; 1129 OscarConnection *conn;
1130 aim_frame_t *fr; 1130 FlapFrame *fr;
1131 aim_snacid_t snacid; 1131 aim_snacid_t snacid;
1132 1132
1133 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)) || !sn) 1133 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)) || !sn)
1134 return -EINVAL; 1134 return -EINVAL;
1135 1135
1147 1147
1148 return 0; 1148 return 0;
1149 } 1149 }
1150 1150
1151 /* Subtype 0x0006 */ 1151 /* Subtype 0x0006 */
1152 static int userinfo(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1152 static int userinfo(OscarSession *sess, aim_module_t *mod, FlapFrame *rx, aim_modsnac_t *snac, ByteStream *bs)
1153 { 1153 {
1154 int ret = 0; 1154 int ret = 0;
1155 aim_rxcallback_t userfunc; 1155 aim_rxcallback_t userfunc;
1156 aim_userinfo_t *userinfo, *userinfo2; 1156 aim_userinfo_t *userinfo, *userinfo2;
1157 aim_tlvlist_t *tlvlist; 1157 aim_tlvlist_t *tlvlist;
1178 userinfo->away_len = tlv->length; 1178 userinfo->away_len = tlv->length;
1179 } 1179 }
1180 1180
1181 /* Caps will be 5 */ 1181 /* Caps will be 5 */
1182 if ((tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1))) { 1182 if ((tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1))) {
1183 aim_bstream_t cbs; 1183 ByteStream cbs;
1184 aim_bstream_init(&cbs, tlv->value, tlv->length); 1184 aim_bstream_init(&cbs, tlv->value, tlv->length);
1185 userinfo->capabilities = aim_locate_getcaps(sess, &cbs, tlv->length); 1185 userinfo->capabilities = aim_locate_getcaps(sess, &cbs, tlv->length);
1186 userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES; 1186 userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES;
1187 } 1187 }
1188 aim_tlvlist_free(&tlvlist); 1188 aim_tlvlist_free(&tlvlist);
1210 * 1210 *
1211 * This is not the same as aim_location_setprofile! 1211 * This is not the same as aim_location_setprofile!
1212 * privacy: 1 to allow searching, 0 to disallow. 1212 * privacy: 1 to allow searching, 0 to disallow.
1213 * 1213 *
1214 */ 1214 */
1215 faim_export int aim_locate_setdirinfo(aim_session_t *sess, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, guint16 privacy) 1215 faim_export int aim_locate_setdirinfo(OscarSession *sess, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, guint16 privacy)
1216 { 1216 {
1217 aim_conn_t *conn; 1217 OscarConnection *conn;
1218 aim_frame_t *fr; 1218 FlapFrame *fr;
1219 aim_snacid_t snacid; 1219 aim_snacid_t snacid;
1220 aim_tlvlist_t *tl = NULL; 1220 aim_tlvlist_t *tl = NULL;
1221 1221
1222 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE))) 1222 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)))
1223 return -EINVAL; 1223 return -EINVAL;
1261 } 1261 }
1262 1262
1263 /* 1263 /*
1264 * Subtype 0x000b - Huh? What is this? 1264 * Subtype 0x000b - Huh? What is this?
1265 */ 1265 */
1266 faim_export int aim_locate_000b(aim_session_t *sess, const char *sn) 1266 faim_export int aim_locate_000b(OscarSession *sess, const char *sn)
1267 { 1267 {
1268 aim_conn_t *conn; 1268 OscarConnection *conn;
1269 aim_frame_t *fr; 1269 FlapFrame *fr;
1270 aim_snacid_t snacid; 1270 aim_snacid_t snacid;
1271 1271
1272 return -EINVAL; 1272 return -EINVAL;
1273 1273
1274 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)) || !sn) 1274 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)) || !sn)
1292 * Subtype 0x000f 1292 * Subtype 0x000f
1293 * 1293 *
1294 * XXX pass these in better 1294 * XXX pass these in better
1295 * 1295 *
1296 */ 1296 */
1297 faim_export int aim_locate_setinterests(aim_session_t *sess, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy) 1297 faim_export int aim_locate_setinterests(OscarSession *sess, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy)
1298 { 1298 {
1299 aim_conn_t *conn; 1299 OscarConnection *conn;
1300 aim_frame_t *fr; 1300 FlapFrame *fr;
1301 aim_snacid_t snacid; 1301 aim_snacid_t snacid;
1302 aim_tlvlist_t *tl = NULL; 1302 aim_tlvlist_t *tl = NULL;
1303 1303
1304 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE))) 1304 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)))
1305 return -EINVAL; 1305 return -EINVAL;
1342 * 0x00000002 - Away message. 1342 * 0x00000002 - Away message.
1343 * 0x00000004 - Capabilities. 1343 * 0x00000004 - Capabilities.
1344 * 0x00000008 - Certification. 1344 * 0x00000008 - Certification.
1345 * @return Return 0 if no errors, otherwise return the error number. 1345 * @return Return 0 if no errors, otherwise return the error number.
1346 */ 1346 */
1347 faim_export int aim_locate_getinfoshort(aim_session_t *sess, const char *sn, guint32 flags) 1347 faim_export int aim_locate_getinfoshort(OscarSession *sess, const char *sn, guint32 flags)
1348 { 1348 {
1349 aim_conn_t *conn; 1349 OscarConnection *conn;
1350 aim_frame_t *fr; 1350 FlapFrame *fr;
1351 aim_snacid_t snacid; 1351 aim_snacid_t snacid;
1352 1352
1353 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)) || !sn) 1353 if (!sess || !(conn = aim_conn_findbygroup(sess, OSCAR_FAMILY_LOCATE)) || !sn)
1354 return -EINVAL; 1354 return -EINVAL;
1355 1355
1366 aim_tx_enqueue(sess, fr); 1366 aim_tx_enqueue(sess, fr);
1367 1367
1368 return 0; 1368 return 0;
1369 } 1369 }
1370 1370
1371 static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1371 static int snachandler(OscarSession *sess, aim_module_t *mod, FlapFrame *rx, aim_modsnac_t *snac, ByteStream *bs)
1372 { 1372 {
1373 1373
1374 if (snac->subtype == 0x0001) 1374 if (snac->subtype == 0x0001)
1375 return error(sess, mod, rx, snac, bs); 1375 return error(sess, mod, rx, snac, bs);
1376 else if (snac->subtype == 0x0003) 1376 else if (snac->subtype == 0x0003)
1379 return userinfo(sess, mod, rx, snac, bs); 1379 return userinfo(sess, mod, rx, snac, bs);
1380 1380
1381 return 0; 1381 return 0;
1382 } 1382 }
1383 1383
1384 static void locate_shutdown(aim_session_t *sess, aim_module_t *mod) 1384 static void locate_shutdown(OscarSession *sess, aim_module_t *mod)
1385 { 1385 {
1386 aim_userinfo_t *del; 1386 aim_userinfo_t *del;
1387 1387
1388 while (sess->locate.userinfo) { 1388 while (sess->locate.userinfo) {
1389 del = sess->locate.userinfo; 1389 del = sess->locate.userinfo;
1391 aim_info_free(del); 1391 aim_info_free(del);
1392 free(del); 1392 free(del);
1393 } 1393 }
1394 } 1394 }
1395 1395
1396 faim_internal int locate_modfirst(aim_session_t *sess, aim_module_t *mod) 1396 faim_internal int locate_modfirst(OscarSession *sess, aim_module_t *mod)
1397 { 1397 {
1398 1398
1399 mod->family = OSCAR_FAMILY_LOCATE; 1399 mod->family = OSCAR_FAMILY_LOCATE;
1400 mod->version = 0x0001; 1400 mod->version = 0x0001;
1401 mod->toolid = 0x0110; 1401 mod->toolid = 0x0110;