OCStackResult InProcServerWrapper::registerPlatformInfo(const OCPlatformInfo platformInfo)
 {
     auto cLock = m_csdkLock.lock();
     OCStackResult result = OC_STACK_ERROR;
     if(cLock)
     {
         std::lock_guard<std::recursive_mutex> lock(*cLock);
         result = OCSetPlatformInfo(platformInfo);
     }
     return result;
 }
OCStackResult SetPlatformInfo()
{
    static const OCPlatformInfo platformInfo =
        {
            .platformID = "IoTivityZigbeeID",
            .manufacturerName = "IoTivity",
            .manufacturerUrl = "http://iotivity.org",
            .modelNumber = "T1000",
            .dateOfManufacture = "January 14th, 2015",
            .platformVersion = "0.9.2",
            .operatingSystemVersion = "7",
            .hardwareVersion = "0.5",
            .firmwareVersion = "0",
            .supportUrl = "http://iotivity.org",
            .systemTime = ""
        };

    return OCSetPlatformInfo(platformInfo);
}

OCStackResult SetDeviceInfo()
{
    static OCDeviceInfo deviceInfo =
        {
            .deviceName = "IoTivity/Zigbee Server Sample",
            .specVersion = "IoTivity/Zigbee Device Spec Version",
        };
    char *dmv = OICStrdup("IoTivity/Zigbee Data Model Version");
    deviceInfo.dataModelVersions = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
    deviceInfo.dataModelVersions->value = dmv;
    char *dup = OICStrdup("oic.wk.d");
    deviceInfo.types = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
    deviceInfo.types->value = dup;
    return OCSetDeviceInfo(deviceInfo);
}

bool processSignal(bool set)
{
    static sig_atomic_t signal = 0;
    if (set)
    {
        signal = 1;
    }

    return signal == 1;
}

void processCancel(int signal)
{
    if(signal == SIGINT)
    {
        processSignal(true);
    }
}
OCStackResult SetPlatformInfo()
{
    static const OCPlatformInfo platformInfo =
        {
            .platformID = "IoTivityZigbeeID",
            .manufacturerName = "IoTivity",
            .manufacturerUrl = "http://iotivity.org",
            .modelNumber = "T1000",
            .dateOfManufacture = "January 14th, 2015",
            .platformVersion = "0.9.2",
            .operatingSystemVersion = "7",
            .hardwareVersion = "0.5",
            .firmwareVersion = "0",
            .supportUrl = "http://iotivity.org",
            .systemTime = ""
        };

    return OCSetPlatformInfo(platformInfo);
}

OCStackResult SetDeviceInfo()
{
    static const OCDeviceInfo deviceInfo =
        {
            .deviceName = "IoTivity/Zigbee Server Sample"
        };

    return OCSetDeviceInfo(deviceInfo);
}

bool processSignal(bool set)
{
    static sig_atomic_t signal = 0;
    if (set)
    {
        signal = 1;
    }

    return signal == 1;
}

void processCancel(int signal)
{
    if(signal == SIGINT)
    {
        processSignal(true);
    }
}
void set_platform_info(things_server_builder_s *builder, char *model_num, char *pver, char *osver, char *hwver, char *fwver, char *venderid, char *mnmn, char *mn_url)
{
	THINGS_LOG_D(TAG, THINGS_FUNC_ENTRY);

	if (model_num == NULL || strlen(model_num) < 1) {
		THINGS_LOG_E(TAG, "Invalid input for registering platform Info");
		return;
	}

	THINGS_LOG_D(TAG, "[/oic/p] Manufacturer :%s", mnmn);
	THINGS_LOG_D(TAG, "[/oic/p] Model Name :%s", model_num);
	THINGS_LOG_D(TAG, "[/oic/p] Ver. Plaform :%s", pver);
	THINGS_LOG_D(TAG, "[/oic/p] Ver. OS :%s", osver);
	THINGS_LOG_D(TAG, "[/oic/p] Ver. HW :%s", hwver);
	THINGS_LOG_D(TAG, "[/oic/p] Ver. FW :%s", fwver);
	THINGS_LOG_D(TAG, "[/oic/p] Ver. vid :%s", venderid);

	OCPlatformInfo platform_info;

	platform_info.platformID = (char *)OCGetServerInstanceIDString();
	platform_info.manufacturerName = mnmn;
	platform_info.modelNumber = model_num;
	platform_info.platformVersion = pver;
	platform_info.operatingSystemVersion = osver;
	platform_info.hardwareVersion = hwver;
	platform_info.firmwareVersion = fwver;

	platform_info.manufacturerUrl = mn_url;
	platform_info.dateOfManufacture = NULL;
	platform_info.supportUrl = NULL;
	platform_info.systemTime = NULL;

	iotivity_api_lock();

	OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, KEY_ATTR_PLATFORM_VENDERID, venderid);
	OCSetPlatformInfo(platform_info);

	iotivity_api_unlock();

	THINGS_LOG_D(TAG, THINGS_FUNC_EXIT);
}
int main(int argc, char* argv[])
{

#ifdef RA_ADAPTER
    char host[] = "localhost";
    char user[] = "test1";
    char pass[] = "intel123";
    char empstr[] = "";
    OCRAInfo_t rainfo = {};

    rainfo.hostname = host;
    rainfo.port = 5222;
    rainfo.xmpp_domain = host;
    rainfo.username = user;
    rainfo.password = pass;
    rainfo.resource = empstr;
    rainfo.user_jid = empstr;
    rainfo.jidbound = jidbound;
#endif

    int opt = 0;
    while ((opt = getopt(argc, argv, "o:s:p:d:u:w:r:j:")) != -1)
    {
        switch(opt)
        {
            case 'o':
                gObserveNotifyType = atoi(optarg);
                break;
#ifdef RA_ADAPTER
            case 's':
                rainfo.hostname = optarg;
                break;
            case 'p':
                rainfo.port = atoi(optarg);
                break;
            case 'd':
                rainfo.xmpp_domain = optarg;
                break;
            case 'u':
                rainfo.username = optarg;
                break;
            case 'w':
                rainfo.password = optarg;
                break;
            case 'j':
                rainfo.user_jid = optarg;
                break;
            case 'r':
                rainfo.resource = optarg;
                break;
#endif
            default:
                PrintUsage();
                return -1;
        }
    }

    if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
    {
        PrintUsage();
        return -1;
    }

#ifdef RA_ADAPTER
    OCSetRAInfo(&rainfo);
#endif

    OIC_LOG(DEBUG, TAG, "OCServer is starting...");

    if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
    {
        OIC_LOG(ERROR, TAG, "OCStack init error");
        return 0;
    }
#ifdef WITH_PRESENCE
    if (OCStartPresence(0) != OC_STACK_OK)
    {
        OIC_LOG(ERROR, TAG, "OCStack presence/discovery error");
        return 0;
    }
#endif

    OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);

    OCStackResult registrationResult =
        SetPlatformInfo(platformID, manufacturerName, manufacturerUrl, modelNumber,
            dateOfManufacture, platformVersion,  operatingSystemVersion,  hardwareVersion,
            firmwareVersion,  supportUrl, systemTime);

    if (registrationResult != OC_STACK_OK)
    {
        OIC_LOG(INFO, TAG, "Platform info setting failed locally!");
        exit (EXIT_FAILURE);
    }

    registrationResult = OCSetPlatformInfo(platformInfo);

    if (registrationResult != OC_STACK_OK)
    {
        OIC_LOG(INFO, TAG, "Platform Registration failed!");
        exit (EXIT_FAILURE);
    }

    registrationResult = SetDeviceInfo(deviceName, specVersion, dataModelVersions);

    if (registrationResult != OC_STACK_OK)
    {
        OIC_LOG(INFO, TAG, "Device info setting failed locally!");
        exit (EXIT_FAILURE);
    }

    OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv");

    registrationResult = OCSetDeviceInfo(deviceInfo);

    if (registrationResult != OC_STACK_OK)
    {
        OIC_LOG(INFO, TAG, "Device Registration failed!");
        exit (EXIT_FAILURE);
    }

    /*
     * Declare and create the example resource: Light
     */
    createLightResource(gResourceUri, &Light);

    // Initialize observations data structure for the resource
    for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
    {
        interestedObservers[i].valid = false;
    }


    /*
     * Create a thread for generating changes that cause presence notifications
     * to be sent to clients
     */

    #ifdef WITH_PRESENCE
    pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
    #endif

    // Break from loop with Ctrl-C
    OIC_LOG(INFO, TAG, "Entering ocserver main loop...");

    DeletePlatformInfo();
    DeleteDeviceInfo();

    signal(SIGINT, handleSigInt);

    while (!gQuitFlag)
    {
        if (OCProcess() != OC_STACK_OK)
        {
            OIC_LOG(ERROR, TAG, "OCStack process error");
            return 0;
        }
    }

    if (observeThreadStarted)
    {
        pthread_cancel(threadId_observe);
        pthread_join(threadId_observe, NULL);
    }

    pthread_cancel(threadId_presence);
    pthread_join(threadId_presence, NULL);

    OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");

    if (OCStop() != OC_STACK_OK)
    {
        OIC_LOG(ERROR, TAG, "OCStack process error");
    }

    return 0;
}
/*
 * Class:     org_iochibity_ServiceManager
 * Method:    configurePlatformSP
 * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_org_iochibity_ServiceManager_configurePlatformSP
  (JNIEnv * env, jclass klass,
   jstring j_platform_id,
   jstring j_mfg_name,
   jstring j_mfg_url,
   jstring j_model_number,
   jstring j_mfg_date,
   jstring j_platform_version,
   jstring j_os_version,
   jstring j_hw_version,
   jstring j_fw_version,
   jstring j_support_url,
   jstring j_sys_time)
{
    OC_UNUSED(klass);
    static OCPlatformInfo platform_info =
	{
	    .platformID			= "",
	    .manufacturerName		= "",
	    .manufacturerUrl		= "",
	    .modelNumber		= "",
	    .dateOfManufacture		= "",
	    .platformVersion		= "",
	    .operatingSystemVersion	= "",
	    .hardwareVersion		= "",
	    .firmwareVersion		= "",
	    .supportUrl			= "",
	    .systemTime			= ""   /* "2015-05-15T11.04" */
	};

    if (j_platform_id == NULL) {
	printf("platform id is null\n");
	j_platform_id = (*env)->NewStringUTF(env, platform_info.platformID);
	platform_info.platformID = (char*) (*env)->GetStringUTFChars(env, j_platform_id, NULL);
    } else {
	platform_info.platformID = (char*) (*env)->GetStringUTFChars(env, j_platform_id, NULL);
	if (platform_info.platformID == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c platform id: [%s]\n", platform_info.platformID);

    if (j_mfg_name == NULL) {
	printf("platform id is null\n");
	j_mfg_name = (*env)->NewStringUTF(env, platform_info.manufacturerName);
	platform_info.manufacturerName = (char*) (*env)->GetStringUTFChars(env, j_mfg_name, NULL);
    } else {
	platform_info.manufacturerName = (char*) (*env)->GetStringUTFChars(env, j_mfg_name, NULL);
	if (platform_info.manufacturerName == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c mfg name: [%s]\n", platform_info.manufacturerName);

    if (j_mfg_url == NULL) {
	printf("platform id is null\n");
	j_mfg_url = (*env)->NewStringUTF(env, platform_info.manufacturerUrl);
	platform_info.manufacturerUrl = (char*) (*env)->GetStringUTFChars(env, j_mfg_url, NULL);
    } else {
	platform_info.manufacturerUrl = (char*) (*env)->GetStringUTFChars(env, j_mfg_url, NULL);
	if (platform_info.manufacturerUrl == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c mfg url: [%s]\n", platform_info.manufacturerUrl);

    if (j_model_number == NULL) {
	printf("platform id is null\n");
	j_model_number = (*env)->NewStringUTF(env, platform_info.modelNumber);
	platform_info.modelNumber = (char*) (*env)->GetStringUTFChars(env, j_model_number, NULL);
    } else {
	platform_info.modelNumber = (char*) (*env)->GetStringUTFChars(env, j_model_number, NULL);
	if (platform_info.modelNumber == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c model nbr: [%s]\n", platform_info.modelNumber);

    if (j_mfg_date == NULL) {
	printf("platform id is null\n");
	j_mfg_date = (*env)->NewStringUTF(env, platform_info.dateOfManufacture);
	platform_info.dateOfManufacture = (char*) (*env)->GetStringUTFChars(env, j_mfg_date, NULL);
    } else {
	platform_info.dateOfManufacture = (char*) (*env)->GetStringUTFChars(env, j_mfg_date, NULL);
	if (platform_info.dateOfManufacture == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c mfg date: [%s]\n", platform_info.dateOfManufacture);

    if (j_platform_version == NULL) {
	printf("platform id is null\n");
	j_platform_version = (*env)->NewStringUTF(env, platform_info.platformVersion);
	platform_info.platformVersion = (char*) (*env)->GetStringUTFChars(env, j_platform_version, NULL);
    } else {
	platform_info.platformVersion = (char*) (*env)->GetStringUTFChars(env, j_platform_version, NULL);
	if (platform_info.platformVersion == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c platform version: [%s]\n", platform_info.platformVersion);

    if (j_os_version == NULL) {
	printf("platform id is null\n");
	j_os_version = (*env)->NewStringUTF(env, platform_info.operatingSystemVersion);
	platform_info.operatingSystemVersion = (char*) (*env)->GetStringUTFChars(env, j_os_version, NULL);
    } else {
	platform_info.operatingSystemVersion = (char*) (*env)->GetStringUTFChars(env, j_os_version, NULL);
	if (platform_info.operatingSystemVersion == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c os version: [%s]\n", platform_info.operatingSystemVersion);

    if (j_hw_version == NULL) {
	printf("platform id is null\n");
	j_hw_version = (*env)->NewStringUTF(env, platform_info.hardwareVersion);
	platform_info.hardwareVersion = (char*) (*env)->GetStringUTFChars(env, j_hw_version, NULL);
    } else {
	platform_info.hardwareVersion = (char*) (*env)->GetStringUTFChars(env, j_hw_version, NULL);
	if (platform_info.hardwareVersion == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c hw version: [%s]\n", platform_info.hardwareVersion);

    if (j_fw_version == NULL) {
	printf("platform id is null\n");
	j_fw_version = (*env)->NewStringUTF(env, platform_info.firmwareVersion);
	platform_info.firmwareVersion = (char*) (*env)->GetStringUTFChars(env, j_fw_version, NULL);
    } else {
	platform_info.firmwareVersion = (char*) (*env)->GetStringUTFChars(env, j_fw_version, NULL);
	if (platform_info.firmwareVersion == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c firmware version: [%s]\n", platform_info.firmwareVersion);

    if (j_support_url == NULL) {
	printf("platform id is null\n");
	j_support_url = (*env)->NewStringUTF(env, platform_info.supportUrl);
	platform_info.supportUrl = (char*) (*env)->GetStringUTFChars(env, j_support_url, NULL);
    } else {
	platform_info.supportUrl = (char*) (*env)->GetStringUTFChars(env, j_support_url, NULL);
	if (platform_info.supportUrl == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c support url: [%s]\n", platform_info.supportUrl);

    if (j_sys_time == NULL) {
	printf("platform id is null\n");
	j_sys_time = (*env)->NewStringUTF(env, platform_info.systemTime);
	platform_info.systemTime = (char*) (*env)->GetStringUTFChars(env, j_sys_time, NULL);
    } else {
	platform_info.systemTime = (char*) (*env)->GetStringUTFChars(env, j_sys_time, NULL);
	if (platform_info.systemTime == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c system time: [%s]\n", platform_info.systemTime);

    printf("Setting platform info...\n");
    OCStackResult op_result;
    op_result = OCSetPlatformInfo(platform_info);
    if (op_result != OC_STACK_OK) {
	// FIXME do sth!
    }

    (*env)->ReleaseStringUTFChars(env, j_platform_id, platform_info.platformID);
    (*env)->ReleaseStringUTFChars(env, j_mfg_name, platform_info.manufacturerName);
    (*env)->ReleaseStringUTFChars(env, j_mfg_url, platform_info.manufacturerUrl);
    (*env)->ReleaseStringUTFChars(env, j_model_number, platform_info.modelNumber);
    (*env)->ReleaseStringUTFChars(env, j_mfg_date, platform_info.dateOfManufacture);
    (*env)->ReleaseStringUTFChars(env, j_platform_version, platform_info.platformVersion);
    (*env)->ReleaseStringUTFChars(env, j_os_version, platform_info.operatingSystemVersion);
    (*env)->ReleaseStringUTFChars(env, j_hw_version, platform_info.hardwareVersion);
    (*env)->ReleaseStringUTFChars(env, j_fw_version, platform_info.firmwareVersion);
    (*env)->ReleaseStringUTFChars(env, j_support_url, platform_info.supportUrl);
    (*env)->ReleaseStringUTFChars(env, j_sys_time, platform_info.systemTime);
}

/*
 * Class:     org_iochibity_ServiceManager
 * Method:    configureDeviceSP
 * Signature: (Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_org_iochibity_ServiceManager_configureDeviceSP
  (JNIEnv * env, jclass klass,
   jstring j_device_name,
   jobjectArray j_types,
   jstring j_spec_version,
   jobjectArray j_data_model_versions)
{
    OC_UNUSED(env);
    OC_UNUSED(klass);
    OC_UNUSED(j_types);
    OC_UNUSED(j_data_model_versions);
    static OCDeviceInfo device_info =
	{
	    .deviceName = "", /* Default Device Name", */
	    /* OCStringLL *types; */
	    .types = NULL,
	    .specVersion = "0.0.0", /* device specification version */
	    // .dataModelVersions = "minDeviceModelVersion"
	    .dataModelVersions = NULL
	};

    if (j_device_name == NULL) {
	printf("device name is null, using default\n");
	j_device_name = (*env)->NewStringUTF(env, device_info.deviceName);
	device_info.deviceName = (char*) (*env)->GetStringUTFChars(env, j_device_name, NULL);
    } else {
	device_info.deviceName = (char*) (*env)->GetStringUTFChars(env, j_device_name, NULL);
	if (device_info.deviceName == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c device name: [%s]\n", device_info.deviceName);

    if (j_spec_version == NULL) {
	printf("spec version is null, using default\n");
	j_spec_version = (*env)->NewStringUTF(env, device_info.specVersion);
	device_info.specVersion = (char*) (*env)->GetStringUTFChars(env, j_spec_version, NULL);
    } else {
	device_info.specVersion = (char*) (*env)->GetStringUTFChars(env, j_spec_version, NULL);
	if (device_info.specVersion == NULL) {
	    THROW_JNI_EXCEPTION("GetStringUTFChars");
	}
    }
    printf("c platform id: [%s]\n", device_info.specVersion);



    printf("Setting device info...\n");
    OCStackResult op_result;
    op_result = OCSetDeviceInfo(device_info);
    switch (op_result) {
    case OC_STACK_OK:
	break;
    case OC_STACK_INVALID_PARAM:
	THROW_STACK_EXCEPTION(op_result, "Java_org_iochibity_OCF_setDeviceInfo");
	/* throw_invalid_param(env, "Java_org_iochibity_OCF_setDeviceInfo"); */
	break;
    default:
        printf("Device Registration failed with result %d!\n", op_result);
	THROW_STACK_EXCEPTION(op_result, "UNKNOWN");
    }

    (*env)->ReleaseStringUTFChars(env, j_device_name, device_info.deviceName);
    (*env)->ReleaseStringUTFChars(env, j_spec_version, device_info.specVersion);
}

/*
 * Class:     org_iochibity_ServiceManager
 * Method:    RegisterDefaultServiceRoutine
 * Signature: (Ljava/lang/Object;Ljava/lang/Object;)I
 */
JNIEXPORT void JNICALL Java_org_iochibity_ServiceManager_registerDefaultServiceRoutine
(JNIEnv * env, jclass klass, jobject j_resource_service_provider, jobject j_callback_param)
{
    OC_UNUSED(env);
    OC_UNUSED(klass);
    OC_UNUSED(j_resource_service_provider);
    OC_UNUSED(j_callback_param);
}