//----------------------------------------------------------------------------------- // sending msg to syslog server defined in EEPROM void syslog_send ( char *msg ) { char *packet = (char *)(eth_buffer+UDP_DATA_START); char *pp = packet; int i = 0; SYSLOG_DEBUG("SYSLOG send %s\r\n", msg); (*((unsigned long*)&syslog_server_ip[0])) = para_getip(SYSLOG_IP_EEPROM_STORE,SYSLOG_IP); SYSLOG_DEBUG("Server: %1i.%1i.%1i.%1i\r\n",syslog_server_ip[0],syslog_server_ip[1],syslog_server_ip[2],syslog_server_ip[3]); //Arp-Request senden unsigned long tmp_ip = (*(unsigned long*)&syslog_server_ip[0]); if ( syslog_server_ip[3] != 0xFF ) // quickhack for broadcast address if ( arp_entry_search(tmp_ip) >= MAX_ARP_ENTRY ) //Arp-Request senden? for ( i=0; i<SYSLOG_ARPRETRIES && (arp_request(tmp_ip) != 1); i++ ); if (i>=SYSLOG_ARPRETRIES) { SYSLOG_ERROR("No SYSLOG server!\r\n"); } // building the packet structure *pp++ = '<'; *pp++ = '0'; *pp++ = '>'; strcpy ( pp, msg ); create_new_udp_packet(strlen(packet),SYSLOG_CLIENT_PORT,SYSLOG_SERVER_PORT,tmp_ip); }
static int toggle_sw_proc_msg( zw_api_ctx_S *ctx, const u8* frame, u8 nodeid ) { int val = -1; SYSLOG_DEBUG( "COMMAND_CLASS_BINARY_TOGGLE_SWITCH - processing message" ); if ((unsigned char)frame[6] == SWITCH_TOGGLE_BINARY_SET) { SYSLOG_DEBUG( "SWITCH_TOGGLE_BINARY_SET received from node %d value %d", nodeid,(unsigned char)frame[7]); val = frame[7]; } else if ((unsigned char)frame[6] == SWITCH_TOGGLE_BINARY_GET) { SYSLOG_DEBUG( "SWITCH_TOGGLE_BINARY_GET received from node %d value %d", nodeid,(unsigned char)frame[7]); val = frame[7]; } else if ((unsigned char)frame[6] == SWITCH_TOGGLE_BINARY_REPORT) { SYSLOG_DEBUG( "SWITCH_TOGGLE_BINARY_REPORT received from node %d value %d", nodeid,(unsigned char)frame[7]); val = frame[7]; } else { SYSLOG_INFO( "%i received from node %d", frame[6], nodeid); goto out; } pthread_mutex_lock( &val_lock ); tsw_val = val; pthread_cond_broadcast( &tsw_value ); pthread_mutex_unlock( &val_lock ); out: return 0; }
static int bin_sw_proc_msg( zw_api_ctx_S *ctx, const u8* frame, u8 nodeid ) { int val = -1; SYSLOG_DEBUG( "COMMAND_CLASS_SWITCH_BINARY - processing message" ); if ((unsigned char)frame[6] == SWITCH_BINARY_SET) { SYSLOG_DEBUG( "SWITCH_BINARY_SET received from node %d value %d", nodeid,(unsigned char)frame[7]); val = frame[7]; } else if ((unsigned char)frame[6] == SWITCH_BINARY_GET) { SYSLOG_DEBUG( "SWITCH_BINARY_GET received from node %d value %d", nodeid,(unsigned char)frame[7]); val = frame[7]; } else if ((unsigned char)frame[6] == SWITCH_BINARY_REPORT) { SYSLOG_DEBUG( "SWITCH_BINARY_REPORT received from node %d value %d", nodeid,(unsigned char)frame[7]); val = frame[7]; } else { SYSLOG_INFO( "%i received from node %d", frame[6], nodeid); goto out; } pthread_mutex_lock( &val_lock ); if ( 0 != zw_node_set_state( nodeid, val ) ) SYSLOG_DEBUG( "Setting node bin switch state failed" ); sw_val = val; pthread_cond_broadcast( &sw_value ); pthread_mutex_unlock( &val_lock ); out: return 0; }
static int xmlconfig_load_node( xmlTextReaderPtr reader ) { int ret; const xmlChar *name; ret = xmlTextReaderRead( reader ); while ( ret == 1 ) { name = xmlTextReaderConstName( reader ); if ( name && (XML_READER_TYPE_END_ELEMENT != xmlTextReaderNodeType( reader )) && ( 0 == xmlStrncmp( name, (const xmlChar *)"Node", 7 ) ) ) { const xmlChar *id = xmlTextReaderGetAttribute( reader, (const xmlChar*)"id" ); const xmlChar *nname = xmlTextReaderGetAttribute( reader, (const xmlChar*)"name" ); const xmlChar *type = xmlTextReaderGetAttribute( reader, (const xmlChar*)"type" ); SYSLOG_DEBUG( "xmlconfig_load_node: Name=%s Id=%s Type=%s", nname, id, type ); ret = zw_node_set_label( atoi((const char*)id), (char *)nname ); if ( ret ) SYSLOG_DEBUG( "xmlconfig_load_node: set label for node(%d) failed %d", atoi((const char*)id), ret ); } if ( (XML_READER_TYPE_END_ELEMENT == xmlTextReaderNodeType( reader )) && (0 == xmlStrncmp(name, (const xmlChar *)"NodeConfig", 10))) break; ret = xmlTextReaderRead( reader ); } return ret; }
int Connection::onError(int fd) { assert(this->fd == fd); SYSLOG_DEBUG("connection fd=%d flow=%d onError", fd, flow); int retval = destroy(); return retval; }
/** * Parse the characters found as the value of an XML tag */ static void _login_xml_charactersHandler(void *ctx, const xmlChar *ch, int len) { int i; char output[API_KEY_LENGTH]; login_info_t *loginInfo = (login_info_t *) ctx; if (len > 0 && len < API_KEY_LENGTH) { for (i = 0; i < len; i++) { //if not equal a LF, CR store the character if ((ch[i] != 10) && (ch[i] != 13)) { output[i] = ch[i]; } } output[i] = '\0'; if (strcmp(loginInfo->xmlTag, "keyExpire") == 0) { // Tag is ok, but do nothing } else if (strcmp(loginInfo->xmlTag, "resultCode") == 0) { loginInfo->resultCode = atoi(output); } else if (strcmp(loginInfo->xmlTag, "key") == 0) { snprintf(apiKey, sizeof(apiKey), "%s", output); libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_API_KEY, apiKey); } else { SYSLOG_DEBUG("Login does not support XML tag %s", loginInfo->xmlTag); } } else { SYSLOG_ERR("Received an XML value that is too long to parse"); } }
/** * Parse the characters found as the value of an XML tag */ static void _getactivationinfo_xml_charactersHandler(void *ctx, const xmlChar *ch, int len) { int i; char output[ACTIVATION_KEY_LENGTH]; getactivationinfo_info_t *getActivationInfo = (getactivationinfo_info_t *) ctx; if (len > 0 && len < ACTIVATION_KEY_LENGTH) { for (i = 0; i < len; i++) { //if not equal a LF, CR store the character if ((ch[i] != 10) && (ch[i] != 13)) { output[i] = ch[i]; } } output[i] = '\0'; if (strcmp(getActivationInfo->xmlTag, "resultCode") == 0) { getActivationInfo->resultCode = atoi(output); } else if (strcmp(getActivationInfo->xmlTag, "deviceActivationKey") == 0) { snprintf(activationKey, sizeof(activationKey), "%s", output); } else { SYSLOG_DEBUG("Activation does not support XML tag %s", getActivationInfo->xmlTag); } } else { SYSLOG_ERR("Received an XML value that is too long to parse"); } }
static int xmlconfig_load_timer( xmlTextReaderPtr reader ) { int ret; const xmlChar *name; ret = xmlTextReaderRead( reader ); while ( ret == 1 ) { name = xmlTextReaderConstName( reader ); if ( name && (XML_READER_TYPE_END_ELEMENT != xmlTextReaderNodeType( reader )) && ( 0 == xmlStrncmp( name, (const xmlChar *)"Timer", 7 ) ) ) { const xmlChar *nodeid = xmlTextReaderGetAttribute( reader, (const xmlChar*)"node" ); const xmlChar *tname = xmlTextReaderGetAttribute( reader, (const xmlChar*)"name" ); const xmlChar *on = xmlTextReaderGetAttribute( reader, (const xmlChar*)"on" ); const xmlChar *off = xmlTextReaderGetAttribute( reader, (const xmlChar*)"off" ); SYSLOG_DEBUG( "xmlconfig_load_timer: Name=%s Id=%s ON=%s, OFF=%s", tname, nodeid, on, off ); } if ( (XML_READER_TYPE_END_ELEMENT == xmlTextReaderNodeType( reader )) && (0 == xmlStrncmp(name, (const xmlChar *)"TimerConfig", 11))) break; ret = xmlTextReaderRead( reader ); } return ret; }
/** * Remove the file descriptor from the list we're tracking * @param fd File descriptor */ void proxyclientmanager_remove(int fd) { int i; SYSLOG_DEBUG("Remove %d", fd); for(i = 0; i < PROXYCLIENTMANAGER_CLIENTS; i++) { if(clients[i].fd == fd) { clients[i].inUse = false; } } }
/** * Add a client socket * @param fd File descriptor to add * @return SUCCESS if the client was added */ error_t proxyclientmanager_add(int fd) { int i; SYSLOG_DEBUG("Add %d", fd); for(i = 0; i < PROXYCLIENTMANAGER_CLIENTS; i++) { if(!clients[i].inUse) { clients[i].inUse = true; clients[i].fd = fd; return SUCCESS; } } return FAIL; }
void MtWorker::workerEntry() { int no = workerId(); SYSLOG_DEBUG("thread-%d (TID=%lu) start...", no, (unsigned long)pthread_self()); while (isRunning) { Message *msg = inQueue->pop(10); if (msg == NULL) { // TODO: idle continue; } gettimeofday(&msg->ts_dequeue, NULL); proc->onMessage(msg); } }
/** * Thread for socket receive communications */ static void *_clientCommThread(void *params) { char inboundMsg[CLIENTSOCKET_INBOUND_MSGSIZE]; // Main loop while (!gTerminate) { memset(inboundMsg, 0, sizeof(inboundMsg)); if(libpipecomm_read(socketFd, inboundMsg, CLIENTSOCKET_INBOUND_MSGSIZE) > 0) { SYSLOG_DEBUG("[client] Received: %s", inboundMsg); application_receive(inboundMsg, strlen(inboundMsg)); } } SYSLOG_INFO("*** Exiting Client Socket Thread ***"); pthread_exit(NULL); return NULL; }
/** * @brief Called when a message has to be sent to the server. this is a standard streamer * if the size of the data to write is larger than size*nmemb, this function * will be called several times by libcurl. * * @param ptr: where data has to be written * @param size: size*nmemb == maximum number of bytes that can be written each time * @param nmemb: size*nmemb == maximum number of bytes that can be written each time * @param userp: ptr to message to write -> inputted by CURLOPT_READDATA call below * * @return number of bytes that were written **/ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp) { struct HttpIoInfo *dataToWrite = (struct HttpIoInfo *) userp; int dataWritten = 0; if (dataToWrite == NULL || dataToWrite->buffer == NULL) { SYSLOG_ERR ("dataToWrite == NULL"); return 0; } if (size * nmemb < 1) { SYSLOG_ERR("size * nmemb < 1"); return 0; } if (dataToWrite->size > 0) { if (dataToWrite->size > (size * nmemb)) { dataWritten = size * nmemb; SYSLOG_DEBUG("dataToWrite->size = %u is larger than size * nmemb = %u", dataToWrite->size, size * nmemb); } else { dataWritten = dataToWrite->size; } memcpy (ptr, dataToWrite->buffer, dataWritten); dataToWrite->buffer += dataWritten; dataToWrite->size -= dataWritten; return dataWritten; /* we return 1 byte at a time! */ } else { return 0; } return 0; }
/** * Parse the characters found as the value of an XML tag */ static void _registrationinfo_xml_charactersHandler(void *ctx, const xmlChar *ch, int len) { int i; char output[ACTIVATION_KEY_LENGTH]; registrationinfo_info_t *registrationInfo = (registrationinfo_info_t *) ctx; if (len > 0 && len < ACTIVATION_KEY_LENGTH) { for (i = 0; i < len; i++) { //if not equal a LF, CR store the character if ((ch[i] != 10) && (ch[i] != 13)) { output[i] = ch[i]; } } output[i] = '\0'; if (strcmp(registrationInfo->xmlTag, "resultCode") == 0) { registrationInfo->resultCode = atoi(output); } else if (strcmp(registrationInfo->xmlTag, "host") == 0) { libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_CLOUD_HOST, output); } else if (strcmp(registrationInfo->xmlTag, "port") == 0) { libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_CLOUD_PORT, output); } else if (strcmp(registrationInfo->xmlTag, "uri") == 0) { libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_CLOUD_URI, output); } else if (strcmp(registrationInfo->xmlTag, "useSSL") == 0) { libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_CLOUD_USE_SSL, output); } else { SYSLOG_DEBUG("Registration does not support XML tag %s", registrationInfo->xmlTag); } } else { SYSLOG_ERR("Received an XML value that is too long to parse"); } }
/** * @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; }
/** * Discover new GADGET devices * * This is an EXAMPLE ONLY! This code won't actually do anything. * It is up to the developer to implement the appropriate discovery mechanism * required to find what devices can be under our control, and then * gather information about those devices so we can pass the device on to * the gadgetmanager to manage its lifetime. * * This will run periodically and update the existing devices on each pass. */ error_t gadgetdiscovery_runOnce() { unsigned int len; struct sockaddr_in cliaddr; struct sockaddr_in destaddr; struct timeval tv; struct timeval curTime; char buffer[GADGET_MAX_MSG_SIZE] = "TYPE: WM-DISCOVER\r\nVERSION:2.5\r\n\r\nservices: com.peoplepower.wm.system*\r\n\r\n"; char *token; int count = 0; struct ip_mreq mc_req; int sock; int ret; int one = 1; int ttl = 3; // Create socket sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { return FAIL; } // Allow socket reuse ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)); if (ret < 0) { return FAIL; } if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) { return FAIL; } ret = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (void*) &ttl, sizeof(ttl)); if (ret < 0) { return FAIL; } // construct a socket bind address structure cliaddr.sin_family = AF_INET; cliaddr.sin_addr.s_addr = htonl(INADDR_ANY); cliaddr.sin_port = htons(0); ret = bind(sock, (struct sockaddr *) &cliaddr, sizeof(cliaddr)); if (ret < 0) { return FAIL; } // construct an IGMP join request structure mc_req.imr_multiaddr.s_addr = inet_addr(GADGET_SSDP_ADDR); mc_req.imr_interface.s_addr = htonl(INADDR_ANY); // send an ADD MEMBERSHIP message via setsockopt if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*) &mc_req, sizeof(mc_req))) < 0) { return FAIL; } // Set destination for multicast address destaddr.sin_family = AF_INET; destaddr.sin_addr.s_addr = inet_addr(GADGET_SSDP_ADDR); destaddr.sin_port = htons(GADGET_SSDP_PORT); // Send the multicast packet len = strlen(buffer); ret = sendto(sock, buffer, len, 0, (struct sockaddr *) &destaddr, sizeof(destaddr)); if (ret < 0) { return FAIL; } SYSLOG_DEBUG("[gadget] SSDP multicast sent, waiting..."); gettimeofday(&curTime, NULL); tv.tv_sec = curTime.tv_sec; while ((curTime.tv_sec - tv.tv_sec) < 3) { gettimeofday(&curTime, NULL); len = sizeof(destaddr); ret = recvfrom(sock, buffer, GADGET_MAX_MSG_SIZE, 0, (struct sockaddr *) &destaddr, &len); if (ret > 0) { count++; token = strtok(buffer, "\r\n"); while (token != NULL) { if (!strncasecmp(token, GADGET_LOCATION_HDR, strlen(GADGET_LOCATION_HDR))) { SYSLOG_DEBUG("Found a wireless microcontroller, base URI: %s", token + strlen(GADGET_LOCATION_HDR)); _gadgetdiscovery_ssdpHandler(token + strlen(GADGET_LOCATION_HDR)); break; } token = strtok(NULL, "\r\n"); } } else { usleep(500000); } } /* send a DROP MEMBERSHIP message via setsockopt */ if ((setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void*) &mc_req, sizeof(mc_req))) < 0) { return FAIL; } return SUCCESS; }
/** * @brief Sends a file through HTTP to a remote computer * * @param url: url of the server (hostname + uri) * @param sslCertPath: location of where the certificate is * @param authToken: authentication token to be added in the header * @param fileName: ptr to message to send. NULL if none * @param rxBuffer: ptr for storing message received by the server -> must exist * @param maxRxBufferSize: max size of rxBuffer in bytes. * @param timeouts: specifies connect and transfer timeouts for the connection * * @return true for success, false for failure */ int libhttpcomm_sendFile(const char *url, const char *sslCertPath, const char *authToken, char *fileName, char *rxBuffer, int maxRxBufferSize, http_timeout_t timeouts) { CURL * curlHandle; CURLcode curlResult; FILE *file = NULL; char tempString[PATH_MAX]; char errorBuffer[CURL_ERROR_SIZE]; int fileSize = 0; struct HttpIoInfo inBoundCommInfo; struct curl_slist *slist = NULL; struct stat fileStats; double connectDuration = 0.0; double transferDuration = 0.0; double nameResolvingDuration = 0.0; long httpResponseCode = 0; long httpConnectCode = 0; long curlErrno = 0; bool_t retVal = true; assert (url); assert (fileName); curlHandle = curl_easy_init(); if (curlHandle) { //creating the curl object // TODO: not sure that setting a pointer to a pointer that is scoped elsewhere is correct. file = fopen(fileName, "r"); if (file == NULL) { SYSLOG_ERR("%s opening %s", strerror(errno), fileName); retVal = false; goto out; } if (stat (fileName, &fileStats) >= 0) { fileSize = (int)fileStats.st_size; }else { SYSLOG_ERR("stats returned %s", strerror(errno)); } slist = curl_slist_append(slist, "Content-Type: application/octet-stream"); snprintf(tempString, sizeof(tempString), "Content-Length: %d", fileSize); slist = curl_slist_append(slist, tempString); SYSLOG_DEBUG("fileName: %s, url: %s, fileSize = %d", fileName, url, fileSize); if (_libhttpcomm_configureHttp(curlHandle, NULL, slist, CURLOPT_POST, url, sslCertPath, authToken, timeouts, NULL) == false) { retVal = false; goto out; } curlResult = curl_easy_setopt(curlHandle, CURLOPT_ERRORBUFFER, errorBuffer); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_ERRORBUFFER", curl_easy_strerror(curlResult)); retVal = false; goto out; } /* pointer to pass to our read function */ // here you must put the file info curlResult = curl_easy_setopt(curlHandle, CURLOPT_READDATA, file); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_READDATA", curl_easy_strerror(curlResult)); retVal = false; goto out; } // sets maximum size of our internal buffer curlResult = curl_easy_setopt(curlHandle, CURLOPT_BUFFERSIZE, maxRxBufferSize); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_BUFFERSIZE", curl_easy_strerror(curlResult)); retVal = false; goto out; } // CURLOPT_WRITEFUNCTION and CURLOPT_WRITEDATA in this context refers to // data received from the server... so curl will write data to us. curlResult = curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, writer); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_WRITEFUNCTION", curl_easy_strerror(curlResult)); retVal = false; goto out; } inBoundCommInfo.buffer = rxBuffer; inBoundCommInfo.size = maxRxBufferSize; curlResult = curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, &inBoundCommInfo); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_WRITEDATA", curl_easy_strerror(curlResult)); retVal = false; goto out; } curlResult = curl_easy_perform(curlHandle); curl_easy_getinfo(curlHandle, CURLINFO_APPCONNECT_TIME, &connectDuration ); curl_easy_getinfo(curlHandle, CURLINFO_NAMELOOKUP_TIME, &nameResolvingDuration ); curl_easy_getinfo(curlHandle, CURLINFO_TOTAL_TIME, &transferDuration ); curl_easy_getinfo(curlHandle, CURLINFO_RESPONSE_CODE, &httpResponseCode ); curl_easy_getinfo(curlHandle, CURLINFO_HTTP_CONNECTCODE, &httpConnectCode ); if (nameResolvingDuration >= 2.0) { SYSLOG_WARNING("connectDuration=%.2lf, nameResolvingDuration=%.2lf, transferDuration=%.2lf, " "httpConnectCode=%ld", connectDuration, nameResolvingDuration, transferDuration, httpConnectCode); } else { SYSLOG_DEBUG("connectDuration=%.2lf, nameResolvingDuration=%.2lf, transferDuration=%.2lf, " "httpConnectCode=%ld", connectDuration, nameResolvingDuration, transferDuration, httpConnectCode); } if (httpResponseCode >= 300 || httpConnectCode >= 300) { SYSLOG_ERR("HTTP error response code: %ld, connect code: %ld", httpResponseCode, httpConnectCode); retVal = false; goto out; } if (curlResult != CURLE_OK) { if (curlResult != CURLE_ABORTED_BY_CALLBACK) { if (curl_easy_getinfo(curlHandle, CURLINFO_OS_ERRNO, &curlErrno) != CURLE_OK) { curlErrno = 0; SYSLOG_ERR("curl_easy_getinfo"); } SYSLOG_ERR("curl_easy_perform: %s, %s for url %s", curl_easy_strerror(curlResult), strerror((int)curlErrno), url); }else { SYSLOG_DEBUG("quitting curl transfer"); } retVal = false; goto out; } // the following is a special case - a time-out from the server is going to return a // string with 1 character in it ... if (strlen(rxBuffer) > 1) { /* put the result into the main buffer and return */ SYSLOG_DEBUG("received msg length %d", strlen(rxBuffer)); }else { if (strlen(rxBuffer) == 1) { SYSLOG_DEBUG("received time-out message from the server"); } rxBuffer[0] = '\0'; goto out; } } else { SYSLOG_ERR("curl_easy_init failed"); retVal = false; } out: fclose(file); _libhttpcomm_closeHttp(curlHandle, slist); return retVal; }
/** * @brief Get a file through HTTP from PPC servers * * @param shareCurlHandle: Curl handle shared across connections * @param url: url of the server (hostname + uri) * @param sslCertPath: location of where the certificate is * @param authToken: authentication token to be added in the header * @param rxFile: FILE ptr to the incoming file * @param maxRxFileSize: max size of the file to receive * @param timeouts: specifies connect and transfer timeouts for the connection * @param ProgressCallback: function pointer that will be called every second during the connection * * @return true for success, false for failure */ int libhttpcomm_getFile(CURLSH * shareCurlHandle, const char *url, const char *sslCertPath, const char *authToken, FILE *rxFile, int maxRxFileSize, http_timeout_t timeouts, int (*ProgressCallback) (void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)) { CURL * curlHandle; CURLcode curlResult; char errorBuffer[CURL_ERROR_SIZE]; struct curl_slist *slist = NULL; double connectDuration = 0.0; double transferDuration = 0.0; double nameResolvingDuration = 0.0; long curlErrno = 0; long httpResponseCode = 0; long httpConnectCode = 0; bool_t retVal = true; assert (rxFile); assert (url); SYSLOG_DEBUG("url: %s", url); curlHandle = curl_easy_init(); if (curlHandle) { if (_libhttpcomm_configureHttp(curlHandle, shareCurlHandle, slist, CURLOPT_HTTPGET, url, sslCertPath, authToken, timeouts, ProgressCallback) == false) { retVal = false; goto out; } curlResult = curl_easy_setopt(curlHandle, CURLOPT_ERRORBUFFER, errorBuffer); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_ERRORBUFFER", curl_easy_strerror(curlResult)); retVal = false; goto out; } // sets maximum size of our internal buffer curlResult = curl_easy_setopt(curlHandle, CURLOPT_BUFFERSIZE, maxRxFileSize); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_BUFFERSIZE", curl_easy_strerror(curlResult)); retVal = false; goto out; } curlResult = curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, rxFile); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_WRITEDATA", curl_easy_strerror(curlResult)); retVal = false; goto out; } curlResult = curl_easy_perform(curlHandle); curl_easy_getinfo(curlHandle, CURLINFO_APPCONNECT_TIME, &connectDuration ); curl_easy_getinfo(curlHandle, CURLINFO_NAMELOOKUP_TIME, &nameResolvingDuration ); curl_easy_getinfo(curlHandle, CURLINFO_TOTAL_TIME, &transferDuration ); curl_easy_getinfo(curlHandle, CURLINFO_RESPONSE_CODE, &httpResponseCode ); curl_easy_getinfo(curlHandle, CURLINFO_HTTP_CONNECTCODE, &httpConnectCode ); if (httpResponseCode >= 300 || httpConnectCode >= 300) { retVal = false; goto out; } if (nameResolvingDuration >= 2.0) { SYSLOG_WARNING("connectDuration=%.2lf, nameResolvingDuration=%.2lf, transferDuration=%.2lf", connectDuration, nameResolvingDuration, transferDuration); } else { SYSLOG_DEBUG("connectDuration=%.2lf, nameResolvingDuration=%.2lf, transferDuration=%.2lf", connectDuration, nameResolvingDuration, transferDuration); } if (curlResult != CURLE_OK) { if (curlResult != CURLE_ABORTED_BY_CALLBACK) { if (curl_easy_getinfo(curlHandle, CURLINFO_OS_ERRNO, &curlErrno) != CURLE_OK) { curlErrno = 0; SYSLOG_ERR("curl_easy_getinfo"); } SYSLOG_ERR("curl_easy_perform: %s, %s for url %s", curl_easy_strerror(curlResult), strerror((int)curlErrno), url); }else { SYSLOG_DEBUG("quitting curl transfer"); } retVal = false; goto out; } } else { SYSLOG_ERR("curl_easy_init failed"); retVal = false; } out: _libhttpcomm_closeHttp(curlHandle, slist); return retVal; }
/** * @brief Sends a message through HTTP to PPC servers * * @param shareCurlHandle: Curl handle shared across connections * @param httpMethod: CURLOPT_POST or CURLOPT_HTTPGET * @param url: url of the server (hostname + uri) * @param sslCertPath: location of where the certificate is * @param authToken: authentication token to be added in the header * @param msgToSendPtr: ptr to message to send. NULL if none * @param msgToSendSize: send of msgToSendPtr * @param rxBuffer: ptr for storing message received by the server -> must exist * @param maxRxBufferSize: max size of rxBuffer in bytes -> if 0 it is assumed that rxBuffer is of type FILE* * @param timeouts: specifies connect and transfer timeouts for the connection * @param ProgressCallback: function pointer that will be called every second during the connection * * @return true for success, false for failure */ int libhttpcomm_postMsg(CURLSH * shareCurlHandle, CURLoption httpMethod, const char *url, const char *sslCertPath, const char *authToken, char *msgToSendPtr, int msgToSendSize, char *rxBuffer, int maxRxBufferSize, http_param_t params, int (*ProgressCallback) (void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)) { CURL * curlHandle = NULL; CURLcode curlResult; char tempString[PATH_MAX]; char errorBuffer[CURL_ERROR_SIZE]; struct HttpIoInfo outBoundCommInfo; struct HttpIoInfo inBoundCommInfo; struct curl_slist *slist = NULL; double connectDuration = 0.0; double transferDuration = 0.0; double nameResolvingDuration = 0.0; long httpResponseCode = 0; long httpConnectCode = 0; long curlErrno = 0; assert (rxBuffer); assert(url); if (params.verbose == true) { if (msgToSendPtr != NULL) { SYSLOG_DEBUG("httpMethod: 0x%x, url: %s, size: %d, outgoing msg: %s", httpMethod, url, msgToSendSize, msgToSendPtr); }else { SYSLOG_DEBUG("httpMethod: 0x%x, url: %s", httpMethod, url); } } rxBuffer[0] = 0; curlHandle = curl_easy_init(); if ( params.key != NULL ) { slist = curl_slist_append(slist, params.key); slist = curl_slist_append(slist, "Content-Type:"); } if (curlHandle) { if ( httpMethod == CURLOPT_POST ) { if ( msgToSendSize > 0 ) { slist = curl_slist_append(slist, "Content-Type: text/xml"); snprintf(tempString, sizeof(tempString), "Content-Length: %d", msgToSendSize); slist = curl_slist_append(slist, tempString); } else if ( msgToSendSize == 0 ) { snprintf(tempString, sizeof(tempString), "Content-Length: %d", msgToSendSize); slist = curl_slist_append(slist, tempString); } } else if ( httpMethod == CURLOPT_HTTPGET ) { if ( params.password != NULL ) { SYSLOG_ERR("password: %s", params.password); slist = curl_slist_append(slist, params.password); } if ( params.key != NULL ) { SYSLOG_ERR("key: %s", params.key); slist = curl_slist_append(slist, params.key); } } if (_libhttpcomm_configureHttp(curlHandle, shareCurlHandle, slist, httpMethod, url, sslCertPath, authToken, params.timeouts, ProgressCallback) == false) { curlErrno = ENOEXEC; goto out; } curlResult = curl_easy_setopt(curlHandle, CURLOPT_ERRORBUFFER, errorBuffer); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_ERRORBUFFER", curl_easy_strerror(curlResult)); curlErrno = ENOEXEC; goto out; } // CURLOPT_READFUNCTION and CURLOPT_READDATA in this context refers to // data to be sent to the server... so curl will read data from us. if(msgToSendPtr != NULL) { if ( msgToSendSize > 0 ) { curlResult = curl_easy_setopt(curlHandle, CURLOPT_READFUNCTION, read_callback); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_READFUNCTION", curl_easy_strerror(curlResult)); curlErrno = ENOEXEC; goto out; } //creating the curl object // TODO: not sure that setting a pointer to a pointer that is scoped elsewhere is correct. outBoundCommInfo.buffer = msgToSendPtr; outBoundCommInfo.size = msgToSendSize; /* pointer to pass to our read function */ // here you must put the file info curlResult = curl_easy_setopt(curlHandle, CURLOPT_READDATA, &outBoundCommInfo); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_READDATA", curl_easy_strerror(curlResult)); curlErrno = ENOEXEC; goto out; } } } // sets maximum size of our internal buffer curlResult = curl_easy_setopt(curlHandle, CURLOPT_BUFFERSIZE, maxRxBufferSize); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_BUFFERSIZE", curl_easy_strerror(curlResult)); curlErrno = ENOEXEC; goto out; } // CURLOPT_WRITEFUNCTION and CURLOPT_WRITEDATA in this context refers to // data received from the server... so curl will write data to us. curlResult = curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, writer); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_WRITEFUNCTION", curl_easy_strerror(curlResult)); curlErrno = ENOEXEC; goto out; } inBoundCommInfo.buffer = rxBuffer; inBoundCommInfo.size = maxRxBufferSize; curlResult = curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, &inBoundCommInfo); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_WRITEDATA", curl_easy_strerror(curlResult)); curlErrno = ENOEXEC; goto out; } curlResult = curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDS, NULL); if (curlResult != CURLE_OK) { SYSLOG_ERR("%s CURLOPT_POSTFIELDS", curl_easy_strerror(curlResult)); curlErrno = ENOEXEC; goto out; } curlResult = curl_easy_perform(curlHandle); curl_easy_getinfo(curlHandle, CURLINFO_APPCONNECT_TIME, &connectDuration ); curl_easy_getinfo(curlHandle, CURLINFO_NAMELOOKUP_TIME, &nameResolvingDuration ); curl_easy_getinfo(curlHandle, CURLINFO_TOTAL_TIME, &transferDuration ); curl_easy_getinfo(curlHandle, CURLINFO_RESPONSE_CODE, &httpResponseCode ); curl_easy_getinfo(curlHandle, CURLINFO_HTTP_CONNECTCODE, &httpConnectCode ); if (httpResponseCode >= 300 || httpConnectCode >= 300) { if (params.verbose == true) SYSLOG_ERR("HTTP error response code:%ld, connect code:%ld", httpResponseCode, httpConnectCode); curlErrno = EHOSTUNREACH; goto out; } if (curlResult != CURLE_OK) { if (curlResult != CURLE_ABORTED_BY_CALLBACK) { if (curl_easy_getinfo(curlHandle, CURLINFO_OS_ERRNO, &curlErrno) != CURLE_OK) { curlErrno = ENOEXEC; SYSLOG_ERR("curl_easy_getinfo"); } if (curlResult == CURLE_OPERATION_TIMEDOUT) curlErrno = ETIMEDOUT; /// time out error must be distinctive else if (curlErrno == 0) curlErrno = ENOEXEC; /// can't be equalt to 0 if curlResult != CURLE_OK if (params.verbose == true) SYSLOG_WARNING("%s, %s for url %s", curl_easy_strerror(curlResult), strerror((int)curlErrno), url); }else { curlErrno = EAGAIN; if (params.verbose == true) SYSLOG_DEBUG("quitting curl transfer"); } goto out; }else if (params.verbose == true) { if (nameResolvingDuration >= 2.0) { SYSLOG_WARNING("connectDuration=%.2lf, nameResolvingDuration=%.2lf, transferDuration=%.2lf, " "httpConnectCode=%ld", connectDuration, nameResolvingDuration, transferDuration, httpConnectCode); } else { SYSLOG_DEBUG("connectDuration=%.2lf, nameResolvingDuration=%.2lf, transferDuration=%.2lf, " "httpConnectCode=%ld", connectDuration, nameResolvingDuration, transferDuration, httpConnectCode); } } // the following is a special case - a time-out from the server is going to return a // string with 1 character in it ... if (strlen(rxBuffer) > 1) { /* put the result into the main buffer and return */ if (params.verbose == true) SYSLOG_DEBUG("received msg length %d", strlen(rxBuffer)); if(msgToSendPtr != NULL && msgToSendSize > 0 ) { msgToSendPtr[0] = 0; } }else { SYSLOG_DEBUG("received time-out message from the server"); rxBuffer[0] = '\0'; curlErrno = EAGAIN; goto out; } } else { SYSLOG_ERR("curl_easy_init failed"); curlErrno = ENOEXEC; } out: _libhttpcomm_closeHttp(curlHandle, slist); return (int)curlErrno; }