sq_dns_sd.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #ifdef WITH_DNS_SD
  2. #include "squirrel.h"
  3. #include <dns_sd.h>
  4. #include <netinet/in.h>
  5. #include <string.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include "sqstdblobimpl.h"
  9. #include "dynamic_library.h"
  10. /*SquiLu
  11. local dns_sd_functions = [
  12. ["void", "TXTRecordCreate", @"TXTRecordRef *txtRecord, uint16_t bufferLen,
  13. void *buffer"],
  14. ["int", "TXTRecordSetValue", @"TXTRecordRef *txtRecord,
  15. const char *key, uint8_t valueSize, const void *value"],
  16. ["void", "TXTRecordDeallocate", "TXTRecordRef *txtRecord"],
  17. ["uint16_t", "TXTRecordGetLength", "const TXTRecordRef *txtRecord"],
  18. ["const void *", "TXTRecordGetBytesPtr", "const TXTRecordRef *txtRecord"],
  19. //next entry should be the last one
  20. //to make valid the test made on load_libpq function
  21. ["DNSServiceErrorType", "DNSServiceRegister", @"DNSServiceRef *sdRef,
  22. DNSServiceFlags flags, uint32_t interfaceIndex,
  23. const char *name, const char *regtype,
  24. const char *domain, const char *host,
  25. uint16_t port, uint16_t txtLen,
  26. const void *txtRecord, DNSServiceRegisterReply callBack,
  27. void *context "],
  28. ];
  29. function write_dns_sd_functions_declaration(){
  30. foreach(k,v in dns_sd_functions) {
  31. putsnl("typedef " + v[0] + " (*" + v[1] + "_t)(" + v[2] + ");");
  32. putsnl("static " + v[1] + "_t dl" + v[1] + " = 0;");
  33. }
  34. }
  35. function write_dns_sd_functions_load(){
  36. foreach(k,v in dns_sd_functions){
  37. putsnl("dl" + v[1] + " = (" + v[1] + "_t) libdns_sd.dlsym(\"" + v[1] + "\");");
  38. putsnl("if(!dl" + v[1] + ") return false;");
  39. }
  40. }
  41. SquiLu*/
  42. static DynamicLibrary libdns_sd;
  43. //@write_dns_sd_functions_declaration();
  44. // generated-code:begin
  45. typedef void (*TXTRecordCreate_t)(TXTRecordRef *txtRecord, uint16_t bufferLen,
  46. void *buffer);
  47. static TXTRecordCreate_t dlTXTRecordCreate = 0;
  48. typedef int (*TXTRecordSetValue_t)(TXTRecordRef *txtRecord,
  49. const char *key, uint8_t valueSize, const void *value);
  50. static TXTRecordSetValue_t dlTXTRecordSetValue = 0;
  51. typedef void (*TXTRecordDeallocate_t)(TXTRecordRef *txtRecord);
  52. static TXTRecordDeallocate_t dlTXTRecordDeallocate = 0;
  53. typedef uint16_t (*TXTRecordGetLength_t)(const TXTRecordRef *txtRecord);
  54. static TXTRecordGetLength_t dlTXTRecordGetLength = 0;
  55. typedef const void * (*TXTRecordGetBytesPtr_t)(const TXTRecordRef *txtRecord);
  56. static TXTRecordGetBytesPtr_t dlTXTRecordGetBytesPtr = 0;
  57. typedef DNSServiceErrorType (*DNSServiceRegister_t)(DNSServiceRef *sdRef,
  58. DNSServiceFlags flags, uint32_t interfaceIndex,
  59. const char *name, const char *regtype,
  60. const char *domain, const char *host,
  61. uint16_t port, uint16_t txtLen,
  62. const void *txtRecord, DNSServiceRegisterReply callBack,
  63. void *context );
  64. static DNSServiceRegister_t dlDNSServiceRegister = 0;
  65. // generated-code:end
  66. #ifdef WIN32
  67. #define LIDNS_SD_NAME "libdns_sd.dll"
  68. #else
  69. #define LIDNS_SD_NAME "libdns_sd.so"
  70. #endif
  71. static bool load_libdns_sd()
  72. {
  73. if(dlDNSServiceRegister) return true;
  74. if(libdns_sd.open(LIDNS_SD_NAME))
  75. {
  76. //@write_dns_sd_functions_load();
  77. // generated-code:begin
  78. dlTXTRecordCreate = (TXTRecordCreate_t) libdns_sd.dlsym("TXTRecordCreate");
  79. if(!dlTXTRecordCreate) return false;
  80. dlTXTRecordSetValue = (TXTRecordSetValue_t) libdns_sd.dlsym("TXTRecordSetValue");
  81. if(!dlTXTRecordSetValue) return false;
  82. dlTXTRecordDeallocate = (TXTRecordDeallocate_t) libdns_sd.dlsym("TXTRecordDeallocate");
  83. if(!dlTXTRecordDeallocate) return false;
  84. dlTXTRecordGetLength = (TXTRecordGetLength_t) libdns_sd.dlsym("TXTRecordGetLength");
  85. if(!dlTXTRecordGetLength) return false;
  86. dlTXTRecordGetBytesPtr = (TXTRecordGetBytesPtr_t) libdns_sd.dlsym("TXTRecordGetBytesPtr");
  87. if(!dlTXTRecordGetBytesPtr) return false;
  88. dlDNSServiceRegister = (DNSServiceRegister_t) libdns_sd.dlsym("DNSServiceRegister");
  89. if(!dlDNSServiceRegister) return false;
  90. // generated-code:end
  91. return true;
  92. }
  93. return false;
  94. }
  95. ////////////////////////////////////////////////////////////////////////////////
  96. static const SQChar *DNS_SD_TAG = _SC("DNS_SD");
  97. static SQRESULT sq_dns_sd_ServiceRegister(HSQUIRRELVM v){
  98. SQ_FUNC_VARS_NO_TOP(v);
  99. TXTRecordRef txtRecord;
  100. DNSServiceRef sdref;
  101. DNSServiceErrorType err;
  102. int ret, result = 0;
  103. SQ_GET_STRING(v, 2, deviceName);
  104. SQ_GET_STRING(v, 3, serviceType);
  105. SQInteger rec_count = sq_getsize(v, 4);
  106. dlTXTRecordCreate(&txtRecord, 0, NULL);
  107. for(int i=0; i < rec_count; ++i){
  108. sq_pushinteger(v, i);
  109. if(SQ_SUCCEEDED(sq_get(v, 4))){
  110. if((sq_gettype(v, 5) == OT_ARRAY) && (sq_getsize(v, 5) == 2)) {
  111. sq_pushinteger(v, 0);
  112. sq_get(v, 5);
  113. SQ_GET_STRING(v, 6, key);
  114. sq_pushinteger(v, 1);
  115. sq_get(v, 5);
  116. SQ_GET_STRING(v, 7, value);
  117. sq_pop(v, 2); //remove key,value
  118. ret = dlTXTRecordSetValue(&txtRecord, key, value_size, value);
  119. if(ret != kDNSServiceErr_NoError) {
  120. sq_throwerror(v, _SC("Array with key, value expected"));
  121. result = SQ_ERROR;
  122. }
  123. } else {
  124. sq_throwerror(v, _SC("Array with key, value expected"));
  125. result = SQ_ERROR;
  126. }
  127. sq_pop(v, 1); //remove value
  128. if(result == SQ_ERROR) {
  129. break;
  130. }
  131. }
  132. }
  133. if(result == 0) {
  134. err = dlDNSServiceRegister(&sdref,0,0,deviceName,serviceType,NULL,NULL,htons(0),
  135. dlTXTRecordGetLength(&txtRecord),dlTXTRecordGetBytesPtr(&txtRecord),NULL,NULL);
  136. if(err != kDNSServiceErr_NoError) {
  137. sq_throwerror(v, _SC("DNS_SD error registering service %d"),err);
  138. result = SQ_ERROR;
  139. }
  140. }
  141. dlTXTRecordDeallocate(&txtRecord);
  142. return result;
  143. }
  144. #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name), sq_dns_sd_##name,nparams,tycheck}
  145. static SQRegFunction sq_dns_sd_methods[] =
  146. {
  147. _DECL_FUNC(ServiceRegister, 4, _SC(".ssa")),
  148. {0,0}
  149. };
  150. #undef _DECL_FUNC
  151. #ifdef __cplusplus
  152. extern "C" {
  153. #endif
  154. SQRESULT sqext_register_DNS_SD(HSQUIRRELVM v)
  155. {
  156. if(load_libdns_sd())
  157. {
  158. sq_pushstring(v,_SC("dns_sd"),-1);
  159. sq_newtable(v);
  160. sq_insert_reg_funcs(v, sq_dns_sd_methods);
  161. sq_newslot(v,-3,SQTrue);
  162. }
  163. else
  164. {
  165. return sq_throwerror(v, _SC("Failed to load libdns_sd !"));
  166. }
  167. return 0;
  168. }
  169. #ifdef __cplusplus
  170. }
  171. #endif
  172. #endif //WITH_DNS_SD