Пример #1
0
//-----------------------------------------------------------------------------------
// 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);
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
0
int Connection::onError(int fd) {
	assert(this->fd == fd);
	SYSLOG_DEBUG("connection fd=%d flow=%d onError", fd, flow);

	int retval = destroy();
	return retval;
}
Пример #6
0
/**
 * 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");
  }
}
Пример #7
0
/**
 * 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");
    }
}
Пример #8
0
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;
}
Пример #9
0
/**
 * 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;
    }
  }
}
Пример #10
0
/**
 * 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;
}
Пример #11
0
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);
	}
}
Пример #12
0
/**
 * 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;
}
Пример #13
0
/**
 * @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;
}
Пример #14
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");
    }
}
Пример #15
0
/**
 * @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;
}
Пример #16
0
/**
 * 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;
}
Пример #17
0
/**
 * @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;
}
Пример #18
0
/**
 * @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;
}
Пример #19
0
/**
 * @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;
}