dns_sd.c

Go to the documentation of this file.
00001 /*##############################################################################
00002 
00003 nIP - nano IP stack
00004 
00005 Copyright (C) 2005 -
00006 Andreas Dittrich, dittrich@informatik.hu-berlin.de
00007 Jon Kowal, kowal@informatik.hu-berlin.de
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00017 GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00023 ##############################################################################*/
00024 /** @file dns_sd.c
00025  *
00026  * DNS Services Discovery Extension.
00027  *
00028  * Provides means to register and unregister services.
00029  *
00030  */
00031 
00032 #include "nip_init.h"
00033 #include "app/dns_sd.h"
00034 #include "app/mdns.h"
00035 #include "mem.h"
00036 #include "nip_error.h"
00037 
00038 #if ( NIP_DNSSD_ENABLE == 1 )
00039 
00040 extern nip_mdns_namestring_id_t nip_mdns_domain;
00041 extern nip_mdns_cache_id_t      nip_mdns_hostname;
00042 extern nip_mem_ptr_t            nip_mdns_cache;
00043 
00044 // Current Service. This should be a list, but to get started, we'll just
00045 // register one service per device.
00046 struct nip_dnssd_service nip_dnssd_services[NIP_DNSSD_MAX_SERVICES];
00047 
00048 /** Register Service for the local host on the .local domain
00049  * @param instance  Instance label e.g. "#myInstance"
00050  * @param service   Service label  e.g. "#_mysrv#_udp"
00051  * @param txt       Text Records   e.g. "#name1=value1#name2=value2"
00052  * @param txtlen    length of txt-string
00053  * @param port      service port in network byte order
00054  * @param priority  Host Priority in network byte order (see RFC 2782)
00055  * @param weight    relative weight for entries with same priority in network
00056  *                  byte order (see RFC 2782)
00057  *
00058  * @note the '#' sign in the above descriptions is to be replaced by the length
00059  * of the following string. For "#myInstance" you'd have to put 0x0A for '#'.
00060  *
00061  * @return ID of registered service. On Error NIP_DNSSD_NO_SERVICE will be
00062  * returned and nip_error be set accordingly. Possible errors are
00063  *  - NIP_E_OUT_OF_RESSOURCES
00064  *  - NIP_E_NOT_CONFIGURED if host name has not yet been configured
00065  *  - NIP_E_INTERNAL_ERROR if some unexpected error occured
00066  *  - ...
00067  */
00068 nip_dnssd_id_t nip_dnssd_register( nip_mem_ptr_t *instance, nip_mem_ptr_t *service, nip_mem_ptr_t *txt, nip_mem_size_t txtlen, uint16_t port, uint16_t priority, uint16_t weight )
00069 {
00070         nip_dnssd_id_t           res    = NIP_DNSSD_NO_SERVICE;
00071         nip_dnssd_id_t           new_id = 1;
00072         nip_error_t              err;
00073         struct nip_dnssd_service *srv;
00074         struct nip_mdns_record   rec;
00075         struct nip_mdns_cache    *cache;
00076         nip_mem_ptr_t            txt_str_ptr;
00077 
00078         /// @todo Get available service ID
00079         /// @todo Manage list with more than one items
00080         srv = &nip_dnssd_services[0];
00081 
00082         // no hostname, try again later
00083         if  ( nip_mdns_hostname == NIP_MDNS_NO_CACHE_ID )
00084         {
00085                 nip_error = NIP_E_NOT_CONFIGURED;
00086                 goto quit;
00087         }
00088 
00089         if ( srv->id != NIP_DNSSD_NO_SERVICE )
00090         {
00091                 nip_error = NIP_E_OUT_OF_RESSOURCES;
00092                 goto quit;
00093         }
00094 
00095         // register names
00096         rec.name.part[0] = NIP_MDNS_REG_STRING( instance);
00097         if ( rec.name.part[0] == NIP_MDNS_NO_NAMESTRING )
00098                 goto quit;
00099         NIP_MDNS_REG_NAME( &rec.name.part[1], 2, service );
00100         if ( rec.name.part[1] == NIP_MDNS_NO_NAMESTRING
00101           || rec.name.part[2] == NIP_MDNS_NO_NAMESTRING )
00102                 goto release_name;
00103         rec.name.part[3] = nip_mdns_domain;
00104 #if NIP_MDNS_MAX_NAME_DEPTH > 4
00105         rec.name.part[4] = NIP_MDNS_NO_NAMESTRING;
00106 #endif
00107 
00108         // copy TXT records to a managed string
00109         txt_str_ptr.id  = nip_mem_alloc( txtlen, txtlen, 0, NULL );
00110         if ( txt_str_ptr.id == NIP_MEM_NULL)
00111                 goto release_name;
00112         txt_str_ptr.ptr = (void*)0;
00113         nip_mem_insert( &txt_str_ptr, txt, txtlen );
00114         // get host name for srv record
00115         cache = nip_mdns_cache_ptr( nip_mdns_hostname );
00116         if ( cache == NULL )
00117         {
00118                 nip_error = NIP_E_INTERNAL_ERROR;
00119                 goto release_name;
00120         }
00121         // set srv record data
00122         nip_memcpy( &rec.data.srv.target, &cache->record.name, sizeof( struct nip_mdns_name ) );
00123         rec.data.srv.weight   = weight;
00124         rec.data.srv.priority = priority;
00125         rec.data.srv.port     = port;
00126         rec.ttl    = NIP_MDNS_DEFAULT_TTL_A;
00127         rec.type   = NIP_MDNS_TYPE_SRV;
00128         nip_mem_release_block( nip_mdns_cache.id );
00129         // register srv record
00130         if ( (err = NIP_MDNS_REGISTER( &srv->srv_rr, &rec )) != NIP_E_OK )
00131         {
00132                 nip_error = err;
00133                 goto release_name;
00134         }
00135 
00136 
00137         // register txt record
00138         rec.ttl   = NIP_MDNS_DEFAULT_TTL;
00139         rec.type  = NIP_MDNS_TYPE_TXT;
00140         rec.data.oth.string = txt_str_ptr.id;
00141         if ( (err = NIP_MDNS_REGISTER( &srv->txt_rr, &rec )) != NIP_E_OK )
00142         {
00143                 NIP_MDNS_UNREGISTER( &srv->srv_rr );
00144                 nip_error = err;
00145                 goto release_name;
00146         }
00147 
00148         // register ptr record
00149         nip_memcpy( &rec.data.ptr.name, &rec.name, sizeof( struct nip_mdns_name ) );
00150         rec.name.part[0] = rec.name.part[1];
00151         rec.name.part[1] = rec.name.part[2];
00152         rec.name.part[2] = rec.name.part[3];
00153         rec.name.part[3] = rec.name.part[4];
00154         rec.ttl   = NIP_MDNS_DEFAULT_TTL_A;
00155         rec.type  = NIP_MDNS_TYPE_PTR;
00156         if ( (err = NIP_MDNS_REGISTER( &srv->ptr_rr, &rec )) != NIP_E_OK )
00157         {
00158                 NIP_MDNS_UNREGISTER( &srv->srv_rr );
00159                 NIP_MDNS_UNREGISTER( &srv->txt_rr );
00160                 nip_error = err;
00161                 goto release_name;
00162         }
00163 
00164         srv->id = new_id;
00165         res     = new_id;
00166 
00167         // register service.dns-sd... ptr
00168 
00169         release_name:
00170                 NIP_MDNS_UNREG_NAME( rec.name.part, 3 );
00171 
00172         quit:
00173                 return res;
00174 }
00175 
00176 #endif

Generated on Thu Jul 10 01:09:29 2008 for NIP by  doxygen 1.5.5