Esempio n. 1
0
int CDECL_CALL main(void)
{
    alljoyn_busattachment bus;
    alljoyn_observer obs;
    alljoyn_observerlistener listener;
    alljoyn_interfacedescription intf;
    alljoyn_interfacedescription_member member;
    QCC_BOOL done;
    const char* intfname = INTF_NAME;

    if (alljoyn_init() != ER_OK) {
        return 1;
    }
#ifdef ROUTER
    if (alljoyn_routerinit() != ER_OK) {
        alljoyn_shutdown();
        return 1;
    }
#endif

    bus = alljoyn_busattachment_create("door_consumer_c", QCC_TRUE);
    setup_busattachment(bus);

    obs = alljoyn_observer_create(bus, &intfname, 1);
    listener_ctx.observer = obs;
    listener_ctx.bus = bus;
    listener = alljoyn_observerlistener_create(&listener_cbs, &listener_ctx);
    alljoyn_observer_registerlistener(obs, listener, QCC_TRUE);

    intf = alljoyn_busattachment_getinterface(bus, INTF_NAME);
    alljoyn_interfacedescription_getmember(intf, "PersonPassedThrough", &member);
    alljoyn_busattachment_registersignalhandler(bus, person_passed_through, member, NULL);

    done = QCC_FALSE;
    while (!done) {
        char input[200];
        char* str;

        printf("> "); fflush(stdout);
        str = fgets(input, sizeof(input), stdin);
        if (str == NULL) {
            break;
        }
        str = strchr(input, '\n');
        if (str) {
            *str = '\0';
        }
        done = !parse(bus, obs, input);
    }

    // Cleanup
    alljoyn_observer_destroy(obs);
    alljoyn_observerlistener_destroy(listener);

    /* Deallocate bus */
    if (bus) {
        alljoyn_busattachment deleteMe = bus;
        bus = NULL;
        alljoyn_busattachment_destroy(deleteMe);
    }

#ifdef ROUTER
    alljoyn_routershutdown();
#endif
    alljoyn_shutdown();
    return 0;
}
Esempio n. 2
0
/** Main entry point */
int CDECL_CALL main(void)
{
    QStatus status = ER_OK;
    char* connectArgs = "unix:abstract=alljoyn";
    alljoyn_interfacedescription testIntf = NULL;
    alljoyn_busobject_callbacks busObjCbs = {
        NULL,
        NULL,
        &busobject_object_registered,
        NULL
    };
    alljoyn_busobject testObj = NULL;
    alljoyn_interfacedescription exampleIntf;
    alljoyn_interfacedescription_member cat_member;
    QCC_BOOL foundMember = QCC_FALSE;
    alljoyn_busobject_methodentry methodEntries[] = {
        { &cat_member, cat_method },
    };
    alljoyn_sessionportlistener_callbacks spl_cbs = {
        accept_session_joiner,
        NULL
    };
    alljoyn_sessionopts opts = NULL;

    if (alljoyn_init() != ER_OK) {
        return 1;
    }
#ifdef ROUTER
    if (alljoyn_routerinit() != ER_OK) {
        alljoyn_shutdown();
        return 1;
    }
#endif

    printf("AllJoyn Library version: %s\n", alljoyn_getversion());
    printf("AllJoyn Library build info: %s\n", alljoyn_getbuildinfo());

    /* Install SIGINT handler */
    signal(SIGINT, SigIntHandler);

    /* Create message bus */
    g_msgBus = alljoyn_busattachment_create("myApp", QCC_TRUE);

    if (g_msgBus != NULL) {
        /* Add org.alljoyn.Bus.method_sample interface */
        status = alljoyn_busattachment_createinterface(g_msgBus, INTERFACE_NAME, &testIntf);
        if (status == ER_OK) {
            alljoyn_interfacedescription_addmember(testIntf, ALLJOYN_MESSAGE_METHOD_CALL, "cat", "ss",  "s", "inStr1,inStr2,outStr", 0);
            alljoyn_interfacedescription_activate(testIntf);
            printf("Interface Created.\n");
        } else {
            printf("Failed to create interface 'org.alljoyn.Bus.method_sample'\n");
        }

        /* Register a bus listener */
        if (ER_OK == status) {
            /* Create a bus listener */
            alljoyn_buslistener_callbacks callbacks = {
                NULL,
                NULL,
                NULL,
                NULL,
                &name_owner_changed,
                NULL,
                NULL,
                NULL
            };
            g_busListener = alljoyn_buslistener_create(&callbacks, NULL);
            alljoyn_busattachment_registerbuslistener(g_msgBus, g_busListener);
        }

        /* Set up bus object */
        testObj = alljoyn_busobject_create(OBJECT_PATH, QCC_FALSE, &busObjCbs, NULL);
        exampleIntf = alljoyn_busattachment_getinterface(g_msgBus, INTERFACE_NAME);
        assert(exampleIntf);
        alljoyn_busobject_addinterface(testObj, exampleIntf);

        foundMember = alljoyn_interfacedescription_getmember(exampleIntf, "cat", &cat_member);
        assert(foundMember == QCC_TRUE);
        if (!foundMember) {
            printf("Failed to get cat member of interface\n");
        }

        status = alljoyn_busobject_addmethodhandlers(testObj, methodEntries, sizeof(methodEntries) / sizeof(methodEntries[0]));
        if (ER_OK != status) {
            printf("Failed to register method handlers for BasicSampleObject\n");
        }

        /* Start the msg bus */
        status = alljoyn_busattachment_start(g_msgBus);
        if (ER_OK == status) {
            printf("alljoyn_busattachment started.\n");
            /* Register  local objects and connect to the daemon */
            status = alljoyn_busattachment_registerbusobject(g_msgBus, testObj);

            /* Create the client-side endpoint */
            if (ER_OK == status) {
                status = alljoyn_busattachment_connect(g_msgBus, connectArgs);
                if (ER_OK != status) {
                    printf("alljoyn_busattachment_connect(\"%s\") failed\n", (connectArgs) ? connectArgs : "NULL");
                } else {
                    printf("alljoyn_busattachment connected to \"%s\"\n", alljoyn_busattachment_getconnectspec(g_msgBus));
                }
            }
        } else {
            printf("alljoyn_busattachment_start failed\n");
        }

        /*
         * Advertise this service on the bus
         * There are three steps to advertising this service on the bus
         * 1) Request a well-known name that will be used by the client to discover
         *    this service
         * 2) Create a session
         * 3) Advertise the well-known name
         */
        /* Request name */
        if (ER_OK == status) {
            uint32_t flags = DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_DO_NOT_QUEUE;
            QStatus status = alljoyn_busattachment_requestname(g_msgBus, OBJECT_NAME, flags);
            if (ER_OK != status) {
                printf("alljoyn_busattachment_requestname(%s) failed (status=%s)\n", OBJECT_NAME, QCC_StatusText(status));
            }
        }

        /* Create session port listener */
        s_sessionPortListener = alljoyn_sessionportlistener_create(&spl_cbs, NULL);

        /* Create session */
        opts = alljoyn_sessionopts_create(ALLJOYN_TRAFFIC_TYPE_MESSAGES, QCC_FALSE, ALLJOYN_PROXIMITY_ANY, ALLJOYN_TRANSPORT_ANY);
        if (ER_OK == status) {
            alljoyn_sessionport sp = SERVICE_PORT;
            status = alljoyn_busattachment_bindsessionport(g_msgBus, &sp, opts, s_sessionPortListener);
            if (ER_OK != status) {
                printf("alljoyn_busattachment_bindsessionport failed (%s)\n", QCC_StatusText(status));
            }
        }

        /* Advertise name */
        if (ER_OK == status) {
            status = alljoyn_busattachment_advertisename(g_msgBus, OBJECT_NAME, alljoyn_sessionopts_get_transports(opts));
            if (status != ER_OK) {
                printf("Failed to advertise name %s (%s)\n", OBJECT_NAME, QCC_StatusText(status));
            }
        }

        if (ER_OK == status) {
            while (g_interrupt == QCC_FALSE) {
    #ifdef _WIN32
                Sleep(100);
    #else
                usleep(100 * 1000);
    #endif
            }
        }
    }
    /* Deallocate sessionopts */
    if (opts) {
        alljoyn_sessionopts_destroy(opts);
    }
    /* Deallocate bus */
    if (g_msgBus) {
        alljoyn_busattachment deleteMe = g_msgBus;
        g_msgBus = NULL;
        alljoyn_busattachment_destroy(deleteMe);
    }

    /* Deallocate bus listener */
    if (g_busListener) {
        alljoyn_buslistener_destroy(g_busListener);
    }

    /* Deallocate session port listener */
    if (s_sessionPortListener) {
        alljoyn_sessionportlistener_destroy(s_sessionPortListener);
    }

    /* Deallocate the bus object */
    if (testObj) {
        alljoyn_busobject_destroy(testObj);
    }

#ifdef ROUTER
    alljoyn_routershutdown();
#endif
    alljoyn_shutdown();
    return (int) status;
}
Esempio n. 3
0
/** TODO: Make this C89 compatible. */
int CDECL_CALL main(int argc, char** argv, char** envArg)
{
    QStatus status = ER_OK;
    char* connectArgs = NULL;
    //alljoyn_interfacedescription testIntf = NULL;
    /* Create a bus listener */
    alljoyn_buslistener_callbacks callbacks = {
        &registered,
        &unregistered,
        &found_advertised_name,
        &lost_advertised_name,
        &name_owner_changed,
        &stopping,
        &disconnected,
        &prop_changed
    };

    if (alljoyn_init() != ER_OK) {
        return 1;
    }
#ifdef ROUTER
    printf("Router Init\n");
    if (alljoyn_routerinit() != ER_OK) {
        alljoyn_shutdown();
        return 1;
    }
#endif

    printf("AllJoyn Library version: %s\n", alljoyn_getversion());
    printf("AllJoyn Library build info: %s\n", alljoyn_getbuildinfo());

    /* Install SIGINT handler */
    signal(SIGINT, SigIntHandler);

    /* Create message bus */
    g_msgBus = alljoyn_busattachment_create("myApp", QCC_TRUE); //Name, Allow remote message
//    g_msgBus = alljoyn_busattachment_create("myApp", QCC_FALSE); //Name, Allow remote message

    /* Add org.alljoyn.Bus.method_sample interface */
#if 0
    status = alljoyn_busattachment_createinterface(g_msgBus, INTERFACE_NAME, &testIntf);
    if (status == ER_OK) {
        printf("Interface Created.\n");
        alljoyn_interfacedescription_addmember(testIntf, ALLJOYN_MESSAGE_METHOD_CALL, "cat", "ss",  "s", "inStr1,inStr2,outStr", 0);
        alljoyn_interfacedescription_addmember(testIntf, ALLJOYN_MESSAGE_METHOD_CALL, "cat2", "ss",  "s", "inStr1,inStr2,outStr", 0);
        alljoyn_interfacedescription_activate(testIntf);
    } else {
        printf("Failed to create interface 'org.alljoyn.Bus.method_sample'\n");
    }
#endif

    /* Start the msg bus */
    if (ER_OK == status) {
        status = alljoyn_busattachment_start(g_msgBus);
        if (ER_OK != status) {
            printf("alljoyn_busattachment_start failed\n");
        } else {
            printf("alljoyn_busattachment started.\n");
        }
    }

    /* Connect to the bus */
    if (ER_OK == status) {
        status = alljoyn_busattachment_connect(g_msgBus, connectArgs);
        if (ER_OK != status) {
            printf("alljoyn_busattachment_connect(\"%s\") failed\n", (connectArgs) ? connectArgs : "NULL");
        } else {
            printf("alljoyn_busattachment connected to \"%s\"\n", alljoyn_busattachment_getconnectspec(g_msgBus));
        }
    }

    g_busListener = alljoyn_buslistener_create(&callbacks, NULL);

    /* Register a bus listener in order to get discovery indications */
    if (ER_OK == status) {
        alljoyn_busattachment_registerbuslistener(g_msgBus, g_busListener);
        printf("alljoyn_buslistener Registered.\n");
    }

    /* Begin discovery on the well-known name of the service to be called */
    if (ER_OK == status) {
        status = alljoyn_busattachment_findadvertisedname(g_msgBus, OBJECT_NAME);
        if (status != ER_OK) {
            printf("alljoyn_busattachment_findadvertisedname failed (%s))\n", QCC_StatusText(status));
        }
    }

    /* Wait for join session to complete */
    while (s_joinComplete == QCC_FALSE && g_interrupt == QCC_FALSE) {
#ifdef _WIN32
        Sleep(10);
#else
        usleep(100 * 1000);
#endif
    }

    if (status == ER_OK && g_interrupt == QCC_FALSE) {
        alljoyn_message reply;
        alljoyn_msgarg inputs;
        size_t numArgs;

        alljoyn_proxybusobject remoteObj = alljoyn_proxybusobject_create(g_msgBus, OBJECT_NAME, OBJECT_PATH, s_sessionId);

#if 1
        status = alljoyn_proxybusobject_introspectremoteobject(remoteObj);
        if (status != ER_OK) {
          printf("Failed to introspect remote object.\n");
        }
#endif

        //alljoyn_interfacedescription alljoynTestIntf = alljoyn_busattachment_getinterface(g_msgBus, INTERFACE_NAME);
        //assert(alljoynTestIntf);
        //alljoyn_proxybusobject_addinterface(remoteObj, alljoynTestIntf);
        //alljoyn_proxybusobject_introspectremoteobject(remoteObj);


#if 0
        alljoynTestIntf = alljoyn_busattachment_getinterface(g_msgBus, "org.freedesktop.DBus.Introspectable");
        assert(alljoynTestIntf);
        alljoyn_proxybusobject_addinterface(remoteObj, alljoynTestIntf);
        
        alljoynTestIntf = alljoyn_busattachment_getinterface(g_msgBus, "org.allseen.Introspectable");
        assert(alljoynTestIntf);
        alljoyn_proxybusobject_addinterface(remoteObj, alljoynTestIntf);
#endif

#if 1
        reply = alljoyn_message_create(g_msgBus);
        inputs = alljoyn_msgarg_array_create(2);
        numArgs = 2;
        status = alljoyn_msgarg_array_set(inputs, &numArgs, "ss", "Hello ", "World!");
        if (ER_OK != status) {
            printf("Arg assignment failed: %s\n", QCC_StatusText(status));
        }
        status = alljoyn_proxybusobject_methodcall(remoteObj, INTERFACE_NAME, "cat", inputs, 2, reply, 5000, 0);
        if (ER_OK == status) {
            char* cat_str;
            status = alljoyn_msgarg_get(alljoyn_message_getarg(reply, 0), "s", &cat_str);
            printf("%s.%s (path=%s) returned \"%s\"\n", INTERFACE_NAME, "cat", OBJECT_PATH, cat_str);
        } else {
            printf("MethodCall on %s.%s failed\n", INTERFACE_NAME, "cat");
        }
#endif
        reply = alljoyn_message_create(g_msgBus);
        inputs = alljoyn_msgarg_array_create(2);
        numArgs = 2;
        status = alljoyn_msgarg_array_set(inputs, &numArgs, "ss", "Hello ", "World!");
        if (ER_OK != status) {
            printf("Arg assignment failed: %s\n", QCC_StatusText(status));
        }
        status = alljoyn_proxybusobject_methodcall(remoteObj, INTERFACE_NAME, "cat2", inputs, 2, reply, 5000, 0);
        if (ER_OK == status) {
            char* cat_str;
            status = alljoyn_msgarg_get(alljoyn_message_getarg(reply, 0), "s", &cat_str);
            printf("%s.%s (path=%s) returned \"%s\"\n", INTERFACE_NAME, "cat2", OBJECT_PATH, cat_str);
        } else {
            printf("MethodCall on %s.%s failed\n", INTERFACE_NAME, "cat2");
        }
#if 0
        status = alljoyn_proxybusobject_methodcall(remoteObj, "org.freedesktop.DBus.Introspectable", "Introspect", NULL, 0, reply, 5000, 0);
        if (ER_OK == status) {
          char* Introspect_str;
          status = alljoyn_msgarg_get(alljoyn_message_getarg(reply, 0), "s", &Introspect_str);
          printf("%s.%s (path=%s) returned \"%s\"\n", "org.freedesktop.DBus.Introspectable", "Introspect", OBJECT_PATH, Introspect_str);
        } else {
          printf("MethodCall on %s.%s failed\n", "org.freedesktop.DBus.Introspectable", "Introspect");
        }
#endif

        alljoyn_proxybusobject_destroy(remoteObj);
        alljoyn_message_destroy(reply);
        alljoyn_msgarg_destroy(inputs);
    }

    /* Deallocate bus */
    if (g_msgBus) {
        alljoyn_busattachment deleteMe = g_msgBus;
        g_msgBus = NULL;
        alljoyn_busattachment_destroy(deleteMe);
    }

    /* Deallocate bus listener */
    alljoyn_buslistener_destroy(g_busListener);

    printf("basic client exiting with status %d (%s)\n", status, QCC_StatusText(status));

#ifdef ROUTER
    printf("Router Shutdown\n");
    alljoyn_routershutdown();
#endif
    alljoyn_shutdown();
    return (int) status;
}
/** Main entry point */
int CDECL_CALL main(void)
{
    QStatus status = ER_OK;
    alljoyn_interfacedescription testIntf = NULL;
    alljoyn_buslistener_callbacks callbacks = {
        NULL,
        NULL,
        &found_advertised_name,
        NULL,
        &name_owner_changed,
        NULL,
        NULL,
        NULL
    };
    unsigned int count = 0;

    if (alljoyn_init() != ER_OK) {
        return 1;
    }
#ifdef ROUTER
    if (alljoyn_routerinit() != ER_OK) {
        alljoyn_shutdown();
        return 1;
    }
#endif

    printf("AllJoyn Library version: %s\n", alljoyn_getversion());
    printf("AllJoyn Library build info: %s\n", alljoyn_getbuildinfo());

    /* Install SIGINT handler */
    signal(SIGINT, SigIntHandler);

    /* Create message bus */
    g_msgBus = alljoyn_busattachment_create("SRPSecurityClientC", QCC_TRUE);

    /* Add org.alljoyn.bus.samples.secure.SecureInterface interface */
    status = alljoyn_busattachment_createinterface_secure(g_msgBus, INTERFACE_NAME, &testIntf, AJ_IFC_SECURITY_REQUIRED);
    if (status == ER_OK) {
        alljoyn_interfacedescription_addmember(testIntf, ALLJOYN_MESSAGE_METHOD_CALL, "Ping", "s",  "s", "inStr1,outStr", 0);
        alljoyn_interfacedescription_activate(testIntf);
    } else {
        printf("Failed to create interface %s\n", INTERFACE_NAME);
    }

    /* Start the msg bus */
    if (ER_OK == status) {
        status = alljoyn_busattachment_start(g_msgBus);
        if (ER_OK != status) {
            printf("alljoyn_busattachment_start failed\n");
        } else {
            printf("alljoyn_busattachment started.\n");
        }
    }

    /*
     * enable security
     * note the location of the keystore file has been specified and the
     * isShared parameter is being set to true. So this keystore file can
     * be used by multiple applications
     */
    if (ER_OK == status) {
        alljoyn_authlistener_callbacks callbacks = {
            request_credentials,
            NULL,
            NULL,
            authentication_complete
        };
        g_authListener = alljoyn_authlistener_create(&callbacks, NULL);

        /*
         * alljoyn_busattachment_enablepeersecurity function is called by
         * applications that want to use authentication and encryption. This
         * function call must be made after alljoyn_busattachment_start and
         * before calling alljoyn_busattachment_connect.
         *
         * In most situations a per-application keystore file is generated.
         * However, this code specifies the location of the keystore file and
         * the isShared parameter is being set to QCC_TRUE. The resulting
         * keystore file can be used by multiple applications.
         */
        status = alljoyn_busattachment_enablepeersecurity(g_msgBus, "ALLJOYN_SRP_KEYX", g_authListener,
                                                          "/.alljoyn_keystore/central.ks", QCC_TRUE);
        if (ER_OK != status) {
            printf("alljoyn_busattachment_enablepeersecurity failed (%s)\n", QCC_StatusText(status));
        } else {
            printf("alljoyn_busattachment_enablepeersecurity Successful\n");
        }
    }

    /* Connect to the bus */
    if (ER_OK == status) {
        status = alljoyn_busattachment_connect(g_msgBus, NULL);
        if (ER_OK != status) {
            printf("alljoyn_busattachment_connect() failed with status: 0x%04x\n", status);
        } else {
            printf("alljoyn_busattachment connected to \"%s\"\n", alljoyn_busattachment_getconnectspec(g_msgBus));
        }
    }

    /* Create a bus listener */
    g_busListener = alljoyn_buslistener_create(&callbacks, NULL);

    /* Register a bus listener in order to get discovery indications */
    if (ER_OK == status) {
        alljoyn_busattachment_registerbuslistener(g_msgBus, g_busListener);
        printf("alljoyn_buslistener Registered.\n");
    }

    /* Begin discovery on the well-known name of the service to be called */
    if (ER_OK == status) {
        status = alljoyn_busattachment_findadvertisedname(g_msgBus, OBJECT_NAME);
        if (status != ER_OK) {
            printf("alljoyn_busattachment_findadvertisedname failed (%s))\n", QCC_StatusText(status));
        }
    }

    /* Wait for join session to complete */
    while (!s_joinComplete && !g_interrupt) {
        if (0 == (count++ % 10)) {
            printf("Waited %u seconds for alljoyn_busattachment_joinsession completion.\n", count / 10);
        }
#ifdef _WIN32
        Sleep(100);
#else
        usleep(100 * 1000);
#endif
    }

    if (status == ER_OK && g_interrupt == QCC_FALSE) {
        alljoyn_message reply;
        alljoyn_msgarg inputs;
        size_t numArgs;

        alljoyn_proxybusobject remoteObj = alljoyn_proxybusobject_create(g_msgBus, OBJECT_NAME, OBJECT_PATH, s_sessionId);
        const alljoyn_interfacedescription alljoynTestIntf = alljoyn_busattachment_getinterface(g_msgBus, INTERFACE_NAME);
        QCC_ASSERT(alljoynTestIntf);
        alljoyn_proxybusobject_addinterface(remoteObj, alljoynTestIntf);

        /*
         * Although AllJoyn will automatically try and establish a secure connection
         * when a method call is made.  It will only allow the user the amount of time
         * specified in the methodcall timeout parameter to enter user input.  For the
         * "Ping" method that is 5 seconds.  This is not a reasonable amount of time
         * for a user to see the security password and enter it.
         *
         * By calling alljoyn_proxybusobject_secureconnection the user will have
         * as much time as they need to to enter the security password to secure
         * the connection.
         */
        status = alljoyn_proxybusobject_secureconnection(remoteObj, QCC_TRUE);
        if (ER_OK == status) {
            reply = alljoyn_message_create(g_msgBus);
            inputs = alljoyn_msgarg_array_create(1);
            numArgs = 1;
            status = alljoyn_msgarg_array_set(inputs, &numArgs, "s", "ClientC says Hello AllJoyn!");

            status = alljoyn_proxybusobject_methodcall(remoteObj, INTERFACE_NAME, "Ping", inputs, 1, reply, 5000, 0);
            if (ER_OK == status) {
                char* ping_str;
                status = alljoyn_msgarg_get(alljoyn_message_getarg(reply, 0), "s", &ping_str);
                printf("%s.%s ( path=%s) returned \"%s\"\n", INTERFACE_NAME, "Ping",
                       OBJECT_PATH, ping_str);
            } else {
                printf("alljoyn_proxybusobject_methodcall on %s.%s failed\n", INTERFACE_NAME, "Ping");
            }
            alljoyn_msgarg_destroy(inputs);
            alljoyn_message_destroy(reply);
        }
        alljoyn_proxybusobject_destroy(remoteObj);
    }

    /* Deallocate bus */
    if (g_msgBus) {
        alljoyn_busattachment deleteMe = g_msgBus;
        g_msgBus = NULL;
        alljoyn_busattachment_destroy(deleteMe);
    }

    /* Deallocate bus listener */
    alljoyn_buslistener_destroy(g_busListener);

    /* Deallocate auth listener */
    alljoyn_authlistener_destroy(g_authListener);

    printf("exiting with status %d (%s)\n", status, QCC_StatusText(status));

#ifdef ROUTER
    alljoyn_routershutdown();
#endif
    alljoyn_shutdown();
    return (int) status;
}
Esempio n. 5
0
/** Main entry point */
int CDECL_CALL main(int argc, char** argv)
{
    QStatus status = ER_OK;
    char* connectArgs = NULL;
    alljoyn_interfacedescription testIntf = NULL;
    unsigned long timeoutMs = ULONG_MAX;
    unsigned long timeMs = 0;

    /* Create a bus listener */
    alljoyn_buslistener_callbacks callbacks = {
        NULL,
        NULL,
        &found_advertised_name,
        NULL,
        &name_owner_changed,
        NULL,
        NULL,
        NULL
    };

    if (argc == 2) {
        char* stopString = NULL;
        /* Multiply by 1000 to convert seconds to milliseconds */
        timeoutMs = strtol(argv[1], &stopString, 10) * 1000;
        if ((timeoutMs == 0) || (stopString[0] != '\0')) {
            printf("Parameter was not valid, please provide a valid integer timeout in seconds or do not provide a parameter to never time out.\n");
            return ER_BAD_ARG_1;
        }
    } else if (argc > 2) {
        printf("This app only accepts a single parameter, an integer connection timeout in seconds. For an unlimited timeout, do not provide a parameter.\n");
        return ER_BAD_ARG_COUNT;
    }


    if (alljoyn_init() != ER_OK) {
        return 1;
    }
#ifdef ROUTER
    if (alljoyn_routerinit() != ER_OK) {
        alljoyn_shutdown();
        return 1;
    }
#endif

    printf("AllJoyn Library version: %s\n", alljoyn_getversion());
    printf("AllJoyn Library build info: %s\n", alljoyn_getbuildinfo());

    /* Install SIGINT handler */
    signal(SIGINT, SigIntHandler);

    /* Create message bus */
    if (status == ER_OK) {
        g_msgBus = alljoyn_busattachment_create("myApp", QCC_TRUE);
    }

    /* Add org.alljoyn.Bus.method_sample interface */
    if (status == ER_OK) {
        status = alljoyn_busattachment_createinterface(g_msgBus, INTERFACE_NAME, &testIntf);
    }

    if (status == ER_OK) {
        printf("Interface Created.\n");
        alljoyn_interfacedescription_addmember(testIntf, ALLJOYN_MESSAGE_METHOD_CALL, "cat", "ss",  "s", "inStr1,inStr2,outStr", 0);
        alljoyn_interfacedescription_activate(testIntf);
    } else {
        printf("Failed to create interface 'org.alljoyn.Bus.method_sample'\n");
    }


    /* Start the msg bus */
    if (ER_OK == status) {
        status = alljoyn_busattachment_start(g_msgBus);
        if (ER_OK != status) {
            printf("alljoyn_busattachment_start failed\n");
        } else {
            printf("alljoyn_busattachment started.\n");
        }
    }

    /* Connect to the bus */
    if (ER_OK == status) {
        status = alljoyn_busattachment_connect(g_msgBus, connectArgs);
        if (ER_OK != status) {
            printf("alljoyn_busattachment_connect(\"%s\") failed\n", (connectArgs) ? connectArgs : "NULL");
        } else {
            printf("alljoyn_busattachment connected to \"%s\"\n", alljoyn_busattachment_getconnectspec(g_msgBus));
        }
    }

    if (status == ER_OK) {
        g_busListener = alljoyn_buslistener_create(&callbacks, NULL);
    }

    /* Register a bus listener in order to get discovery indications */
    if (ER_OK == status) {
        alljoyn_busattachment_registerbuslistener(g_msgBus, g_busListener);
        printf("alljoyn_buslistener Registered.\n");
    }

    /* Begin discovery on the well-known name of the service to be called */
    if (ER_OK == status) {
        status = alljoyn_busattachment_findadvertisedname(g_msgBus, OBJECT_NAME);
        if (status != ER_OK) {
            printf("alljoyn_busattachment_findadvertisedname failed (%s))\n", QCC_StatusText(status));
        }
    }

    /* Wait for join session to complete */
    while ((status == ER_OK) && (s_joinComplete == QCC_FALSE) && (g_interrupt == QCC_FALSE) && (timeMs < timeoutMs)) {
#ifdef _WIN32
        Sleep(10);
#else
        usleep(10 * 1000);
#endif
        timeMs += 10;
    }

    if (timeMs >= timeoutMs) {
        status = ER_BUS_ESTABLISH_FAILED;
        printf("Failed to connect before timeout (%s)\n", QCC_StatusText(status));
    }

    if ((status == ER_OK) && (g_interrupt == QCC_FALSE)) {
        alljoyn_message reply;
        alljoyn_msgarg inputs;
        size_t numArgs;

        alljoyn_proxybusobject remoteObj = alljoyn_proxybusobject_create(g_msgBus, OBJECT_NAME, OBJECT_PATH, s_sessionId);
        const alljoyn_interfacedescription alljoynTestIntf = alljoyn_busattachment_getinterface(g_msgBus, INTERFACE_NAME);
        assert(alljoynTestIntf);
        alljoyn_proxybusobject_addinterface(remoteObj, alljoynTestIntf);

        reply = alljoyn_message_create(g_msgBus);
        inputs = alljoyn_msgarg_array_create(2);
        numArgs = 2;
        status = alljoyn_msgarg_array_set(inputs, &numArgs, "ss", "Hello ", "World!");
        if (ER_OK != status) {
            printf("Arg assignment failed: %s\n", QCC_StatusText(status));
        }
        status = alljoyn_proxybusobject_methodcall(remoteObj, INTERFACE_NAME, "cat", inputs, 2, reply, 5000, 0);
        if (ER_OK == status) {
            char* cat_str;
            status = alljoyn_msgarg_get(alljoyn_message_getarg(reply, 0), "s", &cat_str);
            printf("%s.%s ( path=%s) returned \"%s\"\n", INTERFACE_NAME, "cat", OBJECT_PATH, cat_str);
        } else {
            printf("MethodCall on %s.%s failed\n", INTERFACE_NAME, "cat");
        }

        alljoyn_proxybusobject_destroy(remoteObj);
        alljoyn_message_destroy(reply);
        alljoyn_msgarg_destroy(inputs);
    }

    /* Deallocate bus */
    if (g_msgBus) {
        alljoyn_busattachment deleteMe = g_msgBus;
        g_msgBus = NULL;
        alljoyn_busattachment_destroy(deleteMe);
    }

    /* Deallocate bus listener */
    if (g_busListener) {
        alljoyn_buslistener_destroy(g_busListener);
    }

    printf("basic client exiting with status %d (%s)\n", status, QCC_StatusText(status));

#ifdef ROUTER
    alljoyn_routershutdown();
#endif
    alljoyn_shutdown();
    return (int) status;
}