/** * @brief Generic function to write token into a file in the form (token=value) * * @param fileName: file name for which token will be updated * @param token: Token in file to update: example (ESP_HOST_NAME) * @param value: value of token to update (see definition of max buffer sizes in libconfigio.h) * * @return SUCCESS or FAIL */ error_t libconfigio_write(const char* fileName, const char* token, const char* value) { error_t retVal = SUCCESS; FILE *configFd = NULL; FILE *tmpConfigFd = NULL; // of back up file char line[LINE_MAX]; long filePos = -1; ///where the current value is located long eofPos = -1; ///where the end of the file is char currentValue[LINE_MAX]; char tmpFileName[256]; ///back up file name when copying the file assert(fileName); assert(token); assert(value); memset(line, 0, sizeof(line)); umask(022); // setting permissions to be able to write, open files // note that the config file or a link to it must be in /opt/etc, the source file is in // hub/etc/ if (access(fileName, F_OK) != 0) { SYSLOG_DEBUG("file %s does not exist -> will be created", fileName); }else if (access(fileName, W_OK) != 0) { SYSLOG_DEBUG("no write permission for file %s", fileName); return FAIL; }else { // see if the token already exists -> if so read it and gets its line position in the file. filePos = libconfigio_read (fileName, token, currentValue, sizeof(currentValue)); if(strcmp (value, currentValue) == 0) { // found value and it is the same -> no need to write the flash -> we're done retVal = SUCCESS; goto out; } } if (filePos != -1) //if found the value { //used for backing up of data when rewriting values -> temporary file snprintf(tmpFileName, sizeof(tmpFileName), "%s.tmp", fileName); // TODO: use temp file tmpnam() from Linux tmpConfigFd = fopen(tmpFileName, "w+"); if (tmpConfigFd == NULL) { SYSLOG_ERR("%s -> could not open %s for reading and writing", strerror(errno), tmpFileName); retVal = FAIL; goto out; } // file that we will update configFd = fopen(fileName, "r+"); if (configFd == NULL) { SYSLOG_ERR("%s -> could not open %s for reading and writing", strerror(errno), fileName); retVal = FAIL; goto out; } //find which that existing value is fseek(configFd, filePos, SEEK_SET); //get the first line and then dump it. if (fgets(line, sizeof(line), configFd) == NULL) { SYSLOG_ERR("fgets of first line failed"); } // now we need to cpy the following lines in the temporary file while (!feof (configFd)) { if(fgets(line, sizeof(line), configFd) == NULL) { break; } else if(fputs(line, tmpConfigFd) == EOF) { SYSLOG_ERR("writing tmp file %s, %s", tmpFileName, strerror(errno)); } } //go back to where that line is fseek(configFd, filePos, SEEK_SET); // write the new value fprintf(configFd, "%s=%s\n", token,value); // then recopy the tmp file where we are now //go back to where that line is fseek(tmpConfigFd, 0, SEEK_SET); // now we need to cpy the following lines in the temporary file while (!feof (tmpConfigFd)) { if(fgets(line, sizeof(line), tmpConfigFd) == NULL) { break; } else { if(fputs(line, configFd) == EOF) { SYSLOG_ERR("writing cur file %s, %s", fileName, strerror(errno)); } } } //update so that we know the file size eofPos = ftell(configFd); } else { //create - write token + value in file if either value or file does not exist //find where that existing value is if(configFd != NULL) { fclose(configFd); } configFd = fopen(fileName, "a+"); if (configFd == NULL) { SYSLOG_ERR("%s -> could not open %s for appending", strerror(errno), fileName); retVal = FAIL; goto out; } fprintf(configFd, "%s=%s\n", token,value); } out: if (configFd != NULL) { if (eofPos > 0) { //eliminate junk at the end. if(ftruncate(fileno(configFd), eofPos) < 0) { SYSLOG_ERR("ftruncate failed: %s", strerror(errno)); } } fflush(configFd); fclose(configFd); } if (tmpConfigFd != NULL) { fclose(tmpConfigFd); remove(tmpFileName); } return retVal; }
/** * Get the activation key from the server * @param key Application API key from logging in * @param locationId The location ID for this user * @return the activation key for this device */ char *getactivationinfo_getDeviceActivationKey(const char *key, int locationId) { char url[PATH_MAX]; char baseUrl[PATH_MAX]; char deviceType[8]; char rxBuffer[PROXY_MAX_MSG_LEN]; char headerApiKey[PROXY_HEADER_KEY_LEN]; http_param_t params; getactivationinfo_info_t getActivationInfo; xmlSAXHandler saxHandler = { NULL, // internalSubsetHandler, NULL, // isStandaloneHandler, NULL, // hasInternalSubsetHandler, NULL, // hasExternalSubsetHandler, NULL, // resolveEntityHandler, NULL, // getEntityHandler, NULL, // entityDeclHandler, NULL, // notationDeclHandler, NULL, // attributeDeclHandler, NULL, // elementDeclHandler, NULL, // unparsedEntityDeclHandler, NULL, // setDocumentLocatorHandler, NULL, // startDocument NULL, // endDocument _getactivationinfo_xml_startElementHandler, // startElement NULL, // endElement NULL, // reference, _getactivationinfo_xml_charactersHandler, //characters NULL, // ignorableWhitespace NULL, // processingInstructionHandler, NULL, // comment NULL, // warning NULL, // error NULL, // fatal }; if(activationKeyValid) { return activationKey; } bzero(deviceType, sizeof(deviceType)); bzero(¶ms, sizeof(params)); snprintf(headerApiKey, sizeof(headerApiKey), "FABRUX_API_KEY: %s", login_getApiKey()); // Read the device type from the configuration file if(libconfigio_read(proxycli_getConfigFilename(), CONFIGIO_PROXY_DEVICE_TYPE_TOKEN_NAME, deviceType, sizeof(deviceType)) == -1) { printf("Couldn't read %s in file %s, writing default value\n", CONFIGIO_PROXY_DEVICE_TYPE_TOKEN_NAME, proxycli_getConfigFilename()); libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_PROXY_DEVICE_TYPE_TOKEN_NAME, DEFAULT_PROXY_DEVICETYPE); strncpy(deviceType, DEFAULT_PROXY_DEVICETYPE, sizeof(deviceType)); } // Read the activation URL from the configuration file if(libconfigio_read(proxycli_getConfigFilename(), CONFIGIO_ACTIVATION_URL_TOKEN_NAME, baseUrl, sizeof(baseUrl)) == -1) { printf("Couldn't read %s in file %s, writing default value\n", CONFIGIO_ACTIVATION_URL_TOKEN_NAME, proxycli_getConfigFilename()); libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_ACTIVATION_URL_TOKEN_NAME, DEFAULT_ACTIVATION_URL); strncpy(baseUrl, DEFAULT_ACTIVATION_URL, sizeof(baseUrl)); } snprintf(url, sizeof(url), "%s/locations/%d/deviceActivation/%s", baseUrl, locationId, deviceType); //SYSLOG_INFO("Getting device activation key..."); SYSLOG_INFO("Contacting URL %s\n", url); params.verbose = TRUE; params.timeouts.connectTimeout = HTTPCOMM_DEFAULT_CONNECT_TIMEOUT_SEC; params.timeouts.transferTimeout = HTTPCOMM_DEFAULT_TRANSFER_TIMEOUT_SEC; params.key = headerApiKey; libhttpcomm_sendMsg(NULL, CURLOPT_HTTPGET, url, NULL, NULL, NULL, 0, rxBuffer, sizeof(rxBuffer), params, NULL); SYSLOG_INFO("Server returned: \n%s\n", rxBuffer); getActivationInfo.resultCode = -1; xmlSAXUserParseMemory(&saxHandler, &getActivationInfo, rxBuffer, strlen(rxBuffer)); if(getActivationInfo.resultCode == 0) { printf("Downloaded the secret activation key!\n"); activationKeyValid = true; return activationKey; } else { printf("Error getting activation key. Check the syslogs.\n"); return NULL; } }
/** * Login * @param username * @param password * @return Application API key, or NULL if we couldn't log in */ error_t login_doLogin(const char *username, const char *password) { char baseUrl[PATH_MAX]; char url[PATH_MAX]; char rxBuffer[PROXY_MAX_MSG_LEN]; char headerPassword[PROXY_HEADER_PASSWORD_LEN]; http_param_t params; login_info_t loginInfo; bzero(¶ms, sizeof(params)); xmlSAXHandler saxHandler = { NULL, // internalSubsetHandler, NULL, // isStandaloneHandler, NULL, // hasInternalSubsetHandler, NULL, // hasExternalSubsetHandler, NULL, // resolveEntityHandler, NULL, // getEntityHandler, NULL, // entityDeclHandler, NULL, // notationDeclHandler, NULL, // attributeDeclHandler, NULL, // elementDeclHandler, NULL, // unparsedEntityDeclHandler, NULL, // setDocumentLocatorHandler, NULL, // startDocument NULL, // endDocument _login_xml_startElementHandler, // startElement NULL, // endElement NULL, // reference, _login_xml_charactersHandler, //characters NULL, // ignorableWhitespace NULL, // processingInstructionHandler, NULL, // comment NULL, // warning NULL, // error NULL, // fatal }; // Read the activation URL from the configuration file if(libconfigio_read(proxycli_getConfigFilename(), CONFIGIO_ACTIVATION_URL_TOKEN_NAME, baseUrl, sizeof(baseUrl)) == -1) { printf("Couldn't read %s in file %s, writing default value\n", CONFIGIO_ACTIVATION_URL_TOKEN_NAME, proxycli_getConfigFilename()); libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_ACTIVATION_URL_TOKEN_NAME, DEFAULT_ACTIVATION_URL); strncpy(baseUrl, DEFAULT_ACTIVATION_URL, sizeof(baseUrl)); } snprintf(url, sizeof(url), "%s/login?username=%s", baseUrl, username); snprintf(headerPassword, sizeof(headerPassword), "PASSWORD: %s", password); SYSLOG_INFO("Logging in..."); SYSLOG_INFO("Contacting URL %s\n", url); params.verbose = TRUE; params.timeouts.connectTimeout = HTTPCOMM_DEFAULT_CONNECT_TIMEOUT_SEC; params.timeouts.transferTimeout = HTTPCOMM_DEFAULT_TRANSFER_TIMEOUT_SEC; params.password = headerPassword; libhttpcomm_sendMsg(NULL, CURLOPT_HTTPGET, url, NULL, NULL, NULL, 0, rxBuffer, sizeof(rxBuffer), params, NULL); SYSLOG_INFO("Server returned: \n%s\n", rxBuffer); loginInfo.resultCode = -1; if ( 0 == xmlSAXUserParseMemory(&saxHandler, &loginInfo, rxBuffer, strlen(rxBuffer)) ) { if(loginInfo.resultCode == 0) { printf("Login successful!\n"); SYSLOG_INFO("Login successful"); return SUCCESS; } else { printf("Error logging in\n"); return FAIL; } } printf("Error logging in\n"); return FAIL; }
/** * Register Device * @return */ error_t registerDevice(void) { char url[PATH_MAX]; char baseUrl[PATH_MAX]; char deviceType[8]; char rxBuffer[PROXY_MAX_MSG_LEN]; char headerApiKey[PROXY_HEADER_KEY_LEN]; char eui64[EUI64_STRING_SIZE+8]; http_param_t params; registrationinfo_info_t registrationInfo; bzero(¶ms, sizeof(params)); xmlSAXHandler saxHandler = { NULL, // internalSubsetHandler, NULL, // isStandaloneHandler, NULL, // hasInternalSubsetHandler, NULL, // hasExternalSubsetHandler, NULL, // resolveEntityHandler, NULL, // getEntityHandler, NULL, // entityDeclHandler, NULL, // notationDeclHandler, NULL, // attributeDeclHandler, NULL, // elementDeclHandler, NULL, // unparsedEntityDeclHandler, NULL, // setDocumentLocatorHandler, NULL, // startDocument NULL, // endDocument _registrationinfo_xml_startElementHandler, // startElement NULL, // endElement NULL, // reference, _registrationinfo_xml_charactersHandler, //characters NULL, // ignorableWhitespace NULL, // processingInstructionHandler, NULL, // comment NULL, // warning NULL, // error NULL, // fatal }; bzero(deviceType, sizeof(deviceType)); bzero(¶ms, sizeof(params)); snprintf(headerApiKey, sizeof(headerApiKey), "FABRUX_API_KEY: %s", login_getApiKey()); // Read the device type from the configuration file if(libconfigio_read(proxycli_getConfigFilename(), CONFIGIO_PROXY_DEVICE_TYPE_TOKEN_NAME, deviceType, sizeof(deviceType)) == -1) { printf("Couldn't read %s in file %s, writing default value\n", CONFIGIO_PROXY_DEVICE_TYPE_TOKEN_NAME, proxycli_getConfigFilename()); libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_PROXY_DEVICE_TYPE_TOKEN_NAME, DEFAULT_PROXY_DEVICETYPE); strncpy(deviceType, DEFAULT_PROXY_DEVICETYPE, sizeof(deviceType)); } // Read the activation URL from the configuration file if(libconfigio_read(proxycli_getConfigFilename(), CONFIGIO_ACTIVATION_URL_TOKEN_NAME, baseUrl, sizeof(baseUrl)) == -1) { printf("Couldn't read %s in file %s, writing default value\n", CONFIGIO_ACTIVATION_URL_TOKEN_NAME, proxycli_getConfigFilename()); libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_ACTIVATION_URL_TOKEN_NAME, DEFAULT_ACTIVATION_URL); strncpy(baseUrl, DEFAULT_ACTIVATION_URL, sizeof(baseUrl)); } eui64_toString(eui64, sizeof(eui64)); // https://developer.presencepro.com/cloud/json/devices/001C42DE23CF-4-33F?productId=4 snprintf(url, sizeof(url), "%s/devices/%s?productId=%s", baseUrl, eui64, deviceType); SYSLOG_INFO("Register device..."); SYSLOG_INFO("Contacting URL %s\n", url); params.verbose = TRUE; params.timeouts.connectTimeout = HTTPCOMM_DEFAULT_CONNECT_TIMEOUT_SEC; params.timeouts.transferTimeout = HTTPCOMM_DEFAULT_TRANSFER_TIMEOUT_SEC; params.key = headerApiKey; libhttpcomm_postMsg(NULL, CURLOPT_HTTPPOST, url, NULL, NULL, "", 0, rxBuffer, sizeof(rxBuffer), params, NULL); SYSLOG_INFO("Server returned: \n%s\n", rxBuffer); registrationInfo.resultCode = -1; if ( 0 == xmlSAXUserParseMemory(&saxHandler, ®istrationInfo, rxBuffer, strlen(rxBuffer)) ) { if(registrationInfo.resultCode == 0) { printf("Register device successful!\n"); SYSLOG_INFO("Register device successful"); return SUCCESS; } else { printf("Error register device\n"); return FAIL; } } printf("Error register device\n"); return FAIL; }