Children of the init

Don't feed the geek!
  • Home
  • Imprint / Impressum

Hmmm [UPDATE]

Published by stkn on January 11, 2008 06:33 pm under FreeSWITCH

Well, this updated version actually works with optimization turned on, doesn’t use custom structs for passing data.

It’s now using the sofia-sip way of passing type and value in multiple arguments, this one is still a simplified version though…

There’s some additional code for passing uri parameters each in a single tag now too.

Download: Tag based SIP URI generator example code #2

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>

typedef int switch_core_session_t;

char * sofia_printf_uri( switch_core_session_t *session, ... );

typedef enum {
        URI_TAG_TYPE_USERNAME = 1,
        URI_TAG_TYPE_DESTINATION,
        URI_TAG_TYPE_HOST,
        URI_TAG_TYPE_PORT,
        URI_TAG_TYPE_PARAMETER,
        URI_TAG_TYPE_PARAMETER_LIST,
        URI_TAG_TYPE_URIONLY
} uri_tag_type;

#define URI_TAG_USERNAME(x)                URI_TAG_TYPE_USERNAME, (x)
#define URI_TAG_DESTINATION(x)                URI_TAG_TYPE_DESTINATION, (x)
#define URI_TAG_HOST(x)                        URI_TAG_TYPE_HOST, (x)
#define URI_TAG_PARAMETER(n, v)                URI_TAG_TYPE_PARAMETER, (n), (v)
#define URI_TAG_PARAMETER_LIST(x)        URI_TAG_TYPE_PARAMETER_LIST, (x)

#define URI_TAG_PORT(x)                URI_TAG_TYPE_PORT, (x)
#define URI_TAG_URI_ONLY(x)        URI_TAG_TYPE_URIONLY, (x)

#define TAG_END                 NULL

#define URI_MAX_PARAMS                10

char * sofia_printf_uri( switch_core_session_t *session, ... )
{
        va_list ap;
        char *username = NULL,
                *destination = NULL,
                *host = NULL,
                *param_str = NULL,
                *uri_str = NULL;
        struct { char *name, *val; } param[URI_MAX_PARAMS];
        int tag, port = 0, uri_only = 0, num_params = 0, len_params = 0;

        va_start( ap, session );
        while( 1 ) {
                tag = va_arg( ap, int );
                if( !tag )
                        break;

                switch( tag ) {
                case URI_TAG_TYPE_USERNAME:
                        username = va_arg( ap, char * );
                        break;

                case URI_TAG_TYPE_DESTINATION:
                        destination = va_arg( ap, char * );
                        break;

                case URI_TAG_TYPE_HOST:
                        host = va_arg( ap, char * );
                        break;

                case URI_TAG_TYPE_PARAMETER:
                        param[num_params].name = va_arg( ap, char * );
                        param[num_params].val  = va_arg( ap, char * );
                        len_params += strlen(param[num_params].name) + strlen(param[num_params].val);
                        num_params++;
                        break;

                case URI_TAG_TYPE_PARAMETER_LIST:
                        param_str = va_arg( ap, char * );
                        num_params = -1;
                        break;

                case URI_TAG_TYPE_PORT:
                        port = va_arg( ap, int );
                        break;

                case URI_TAG_TYPE_URIONLY:
                        uri_only = va_arg( ap, int );
                        break;

                default:
                        printf( "Unknown tag type\n" );
                }
        }
        va_end( ap );

        /*
         * We need at least host and destination here
         */
        if( !host ) {
                printf( "no host tag specified\n" );
                return NULL;
        }

        if( !destination ) {
                printf( "no destination tag specified\n" );
                return NULL;
        }

        /*
         * Default value
         */
        if( !username )
                username = "user";

        /*
         * Ugly code ahead...
         * Now if we'd manually allocate memory here we could count string lengths
         * and reserve enough room for the uri incl. parameters in one go and
         * put the params in after snprint'ing the first part...
         * (saving us the trouble of using alloca here)
         */
        if( num_params > 0 ) {
                int n, len;
                char *p;

                param_str = alloca( len_params + num_params );
                if( !param_str )
                        return NULL;

                p = param_str;

                for( n=0; n < num_params; n++ ) {
                        len = strlen( param[n].name );

                        memcpy( p, param[n].name, len );
                        p += len;

                        *p++ = '=';

                        len = strlen( param[n].val );

                        memcpy( p, param[n].val, len );
                        p += len;

                        if( n < num_params - 1 )
                                *p++ = '&';
                }
                *p = '\0';

        } else if( num_params == 0 ) {
                param_str = "";
        }

        /*
         * The (fugly) output part
         */
        if( !uri_only ) {
                if( port ) {
                        printf( "\"%s\" <sip:%s@%s:%d>%s%s\n",
                                username,
                                destination,
                                host,
                                port,
                                num_params ? ";" : "",
                                param_str );
                } else {
                        printf( "\"%s\" <sip:%s@%s>%s%s\n",
                                username,
                                destination,
                                host,
                                num_params ? ";" : "",
                                param_str );
                }
        } else {
                if( port ) {
                        printf( "sip:%s@%s:%d%s%s\n",
                                destination,
                                host,
                                port,
                                num_params ? ";" : "",
                                param_str );
                } else {
                        printf( "sip:%s@%s%s%s\n",
                                destination,
                                host,
                                num_params ? ";" : "",
                                param_str );
                }
        }
        return uri_str;
}

int main( void )
{
        switch_core_session_t session;

        printf( "\nCreating full uri...\n" );
        sofia_printf_uri( &session,
                                URI_TAG_USERNAME( "foobar" ),
                                URI_TAG_HOST( "konata" ),
                                URI_TAG_PORT( 1234 ),
                                URI_TAG_DESTINATION( "myext" ),
                                URI_TAG_PARAMETER( "transport", "tls" ),
                                URI_TAG_PARAMETER( "rport", "12345" ),
                                TAG_END );

        printf( "\nCreating uri only (output w/o username)...\n" );
        sofia_printf_uri( &session,
                                URI_TAG_USERNAME( "foobar" ),
                                URI_TAG_HOST( "konata" ),
                                URI_TAG_PORT( 1234 ),
                                URI_TAG_DESTINATION( "myext" ),
                                URI_TAG_URI_ONLY( 1 ),
                                URI_TAG_PARAMETER( "transport", "tls" ),
                                TAG_END );

        printf( "\nCreating full uri w/o port...\n" );
        sofia_printf_uri( &session,
                                URI_TAG_USERNAME( "foobar" ),
                                URI_TAG_HOST( "konata" ),
                                URI_TAG_DESTINATION( "myext" ),
                                URI_TAG_PARAMETER_LIST( "transport=tls;bla=foo" ),
                                TAG_END );

        return 0;
}

      		

No Comment

Comments are closed.

Posting your comment.

  • Categories

    • Development (39)
      • FreeSWITCH (23)
      • FreeTDM (2)
      • OpenZAP (9)
    • Hardware (1)
    • Misc (2)
  • Pages

    • About
    • Imprint / Impressum
  • Archives

    • January 2011
    • November 2010
    • June 2010
    • February 2010
    • January 2010
    • December 2009
    • October 2009
    • August 2009
    • July 2009
    • June 2009
    • April 2009
    • February 2009
    • January 2009
    • December 2008
    • November 2008
    • October 2008
    • March 2008
    • January 2008
    • November 2007
  • Meta

    • Log in
    • Entries feed
    • Comments feed
    • WordPress.org

Copyright © 2022 Children of the init
WordPress Theme based on Light Theme