IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Embarqué Discussion :

SIM808 / HTTP, réponse serveur avec POST [SAM D]


Sujet :

Embarqué

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 46
    Points : 11
    Points
    11
    Par défaut SIM808 / HTTP, réponse serveur avec POST
    Bonjour,

    J'ai une board équipé d'une SIM808, et je suis en train de mettre en place le système d'api de mon programme.
    Les api sont déjà créer et fonctionnel sur le serveur http (Postman envoi et reçois sans problème).

    Cependant, avec les fonctions que j'ai créées, je ne reçois pas de réponse du serveur lors de mon post, alors qu'il y en a une.

    La fonction pour le POST :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    int8_t post_http(char *url, char *data)
    {
    	char buffer[200];
    	int8_t answer, success = 0;
    
    	if ((answer = sendATcommand("AT+HTTPPARA=\"CID\",1\r\n", "OK", NULL, NULL, 5000, 1)) == 1) // Sets CID parameter
    	{
    		sendATcommand("AT+HTTPPARA=\"CONTENT\",\"application/json\"\r\n", "OK", NULL, NULL, 5000, 1);
    		
    		snprintf(buffer, sizeof(buffer), "AT+HTTPPARA=\"URL\",\"%s\"\r\n", url); // Sets url
    		sendATcommand(buffer, "OK", NULL, NULL, 3000, 1);
    		delay_ms(3000);
    		
    		snprintf(buffer, sizeof(buffer), "AT+HTTPDATA=%d,120000\r\n", strlen(data)); //Précise le nombre de bytes a récupérer, et le temps max (bytes,temps)
    		sendATcommand(buffer, "DOWNLOAD", NULL, NULL, 1000, 1);
    
    		snprintf(buffer, sizeof(buffer), "%s\r\n", data); //Chargement du buffer a envoyer
    		sendATcommand(buffer, "OK", NULL, NULL, -1, 1);
    		delay_s(1);
    		
    		answer = sendATcommand("AT+HTTPACTION=1\r\n", "OK", "200", NULL, 10000000, 1); //Envoi du buffer
    		delay_s(5);
    		if (answer == 1 || answer == 2) //200 Success
    		{
    			sendATcommand("AT+HTTPREAD\r\n", "+HTTPREAD", NULL, NULL, -1, 1); //Mode reception
    			readline(3000, 1); //Lecture de la réponse du serveur
    			success = 1;
    		}
    		else
    			printf("POST HTTP : server unavaible\r\n");
    	}
    	return (success);
    }
    la fonction pour le GET :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    int8_t get_http(char *url, char *data)
    {
    	char buffer[250];
    	int8_t answer, success = 0;
    
    	if ((answer = sendATcommand("AT+HTTPPARA=\"CID\",1\r\n", "OK", NULL, NULL, 5000, 1)) == 1)
    	{
    		snprintf(buffer, sizeof(buffer), "AT+HTTPPARA=\"URL\",\"%s\"\r\n", url);
    		sendATcommand(buffer, "OK", NULL, NULL, 2000, 1);
    		
    		sendATcommand("AT+HTTPACTION=0\r\n", "200", NULL, NULL, 10000000, 1);
    		delay_s(5);
    		
    		sendATcommand("AT+HTTPREAD\r\n", "+HTTPREAD", NULL, NULL, 1000, 1);
    		success = readline(3000, 1);
    	}
    	return (success);
    }
    la fonction pour lire le retour :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    uint8_t readline(uint16_t timeout)
    {
    	uint8_t buffer[255];
    
    	usart_read_buffer_wait(&usart_instance_sim808, &buffer, 255);
    	printf("%s", buffer);
    	return (1);
    }
    Voici l’exécution :

    Usart init
    AT+CSQ
    +CSQ: 20,0

    OK
    module is on
    AT+CPIN?
    +CPIN: READY

    OK
    AT+SAPBR=3,1,"CONTYPE","GPRS"
    OK
    AT+SAPBR=3,1,"APN","free"
    OK
    AT+SAPBR=2,1
    +SAPBR: 1,1,"10.128.xxx.x" // c'est moi qui ai mis les 'x'

    OK
    AT+HTTPINIT
    OK
    http initialized
    AT+HTTPPARA="CID",1
    OK
    AT+HTTPPARA="URL","http://2xx.xxx.xxx.xx:xxxx/api/url/xxxx"
    OK
    AT+HTTPPARA="CONTENT","application/json"
    OK
    AT+HTTPDATA=104,120000
    DOWNLOAD

    OK
    AT+HTTPACTION=1
    OK

    /* HTTPREAD est ici ! mais rien reçu :(
    */

    AT+SAPBR=0,1
    http ended
    Je vois dans la datasheet de la sim808, page 261 "Read data when AT+HTTPACTION=0 or AT+HTTPDATA is executed.". Cela signifie que je ne peux pas recevoir de réponse du serveur quand je suis dans le mode "POST" (HTTPACTION=1) ?

    Merci d'avance ! :)

  2. #2
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 46
    Points : 11
    Points
    11
    Par défaut
    Bonjour, j'en profite pour "UP svp !"

    J'essaye de faire un GET a la place du POST (plus simple)

    Voici les commandes que j’exécute :

    AT
    AT+CSQ
    ATE0
    AT+CMEE=2
    AT+CPIN?
    AT+CPIN=1234
    AT+COPS?
    AT+CREG?
    AT+SAPBR=3,1,"CONTYPE","GPRS"
    AT+SAPBR=3,1,"APN","free"
    AT+SAPBR=2,1
    AT+SAPBR=1,1
    AT+HTTPINIT
    AT+HTTPPARA="CID",1
    AT+HTTPPARA="URL","http://xxx.xxx.xxx.xxxxx/hello/cracked"
    AT+HTTPACTION=0
    Délai 10 sec
    AT+HTTPREAD
    AT+HTTPTERM

    Lors du HTTPACTION=0 je suis censé recevoir un "HTTPACTION=0 '\n' OK '\r\n'+HTTPACTION=0,200:13" et lors du HTTPREAD je suis censé avoir "HTTPREAD '\n' OK '\r\n' +HTTPREAD="hello cracked"".
    Mon problème est que le HTTPACTION donne "HTTPACTION=0 '\n' OK '\r\n'" et mon HTTPREAD donne "HTTPREAD '\n'".

    Le serveur reçoit bien la requête et envoi bien sa réponse, il n'y a pas de problèmes de stabilité du courant pour la sim808 (il y a un condo et son alimentation a assez de puissance pour suivre).
    Une idée ? je suis perdu, je ne vois vraiment pas le pb ....

    Merci

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Je vais partir du principe que tu as la main sur ton serveur et que tu as correctement vérifié que le serveur reçoit une requête valide et répond une trame valide.

    Quand tu montres des commandes AT, il s'agit d'une interaction en ligne de commandes dans un terminal ou il s'agit de ce que tu penses exécuter via ton programme C ?

    Je suis étonné de voir des trames HTTP avec juste un \n et non \r\n. C'est normal ?

    On ne voit pas l'implémentation de la fonction sendATcommand(). C'est une fonction que tu as écrite ou qui vient d'une bibliothèque.

    Ta fonction readline() ne parait fausse. En effet, malgré son nom, elle ne lit pas une ligne entière. Elle lit 255 caractères. Et encore, comme on ne connait pas la fonction usart_read_buffer_wait(), on ne sait pas si c'est garanti de lire 255 caractères ou si c'est le maximum de caractères qui seront lus. De plus, le paramètre timeout n'est pas utilisé.

    @+

  4. #4
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 46
    Points : 11
    Points
    11
    Par défaut
    Bonjour Bktero, merci de ta réponse !

    Je vais partir du principe que tu as la main sur ton serveur et que tu as correctement vérifié que le serveur reçoit une requête valide et répond une trame valide.
    Oui j'ai la main sur le serveur HTTP, et oui nous (moi et mes collègues) avons vérifié la validité de la requête et de la réponse.

    Quand tu montres des commandes AT, il s'agit d'une interaction en ligne de commandes dans un terminal ou il s'agit de ce que tu penses exécuter via ton programme C ?
    C'est dans un terminal en ligne de commandes, j'ai deux prototypes, l'un équipé d'un Edison, d'un ATSAMD20J18 et d'une SIM808, l'autre étant le même sans le Edison.
    Le premier utilise l'Edison dont il est équipé pour communiquer directement avec la SIM808.
    Le second utilise un programme C pour envoyer les commandes (c'est dans celui-ci que ce trouve sendATcommand; readline; usart_read_buffer_wait - fonction lib ASF de Atmel) a la SIM808.
    Le programme C est censé envoyer les mêmes commandes que celle que je fais, mais je n'obtiens pas le même comportement.

    Je suis étonné de voir des trames HTTP avec juste un \n et non \r\n. C'est normal ?
    Tu parles de "HTTPACTION=0 '\n' OK '\r\n'+HTTPACTION=0,200:13" ? Je pense que cela vient d'un manque de connaissance dans l'affichage des réponses.

    On ne voit pas l'implémentation de la fonction sendATcommand(). C'est une fonction que tu as écrite ou qui vient d'une bibliothèque.
    C'est une fonction que j'ai écrite qui utilise des fonctions d'une bibliothèque (usart_read_buffer_wait() et usart_write_buffer_wait()), ou plus exactement réécrite, mais j'ai conservé son fonctionnement. J'ai tout saisi et compris de cette fonction, mais je ne connais pas bien le fonctionnement de la SIM808.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    uint8_t *response;
    
    int8_t sendATcommand(const uint8_t *ATcommand, const uint8_t *expected_answer1, const uint8_t *expected_answer2, int8_t *buffer, uint32_t timeout, int8_t display)
    {
    	uint8_t answer = 0;
    	static int debut = 1;
    
    	if (debut == 1)
    	{
    		response = calloc(sizeof(uint8_t), 512);
    		debut = 0;
    	}
    	else
    	{
    		memset(response, 0, 512);
    	}
    	
    	if (((int)timeout == -1) && (expected_answer2 == NULL))	timeout = 100000;
    	
    	usart_write_buffer_wait(&usart_instance_sim808, ATcommand, strlen((const char *)ATcommand));    // Send the AT command
    	usart_read_buffer_wait(&usart_instance_sim808, response, 512);
    	
    	if (strstr((char *)response, (const char *)expected_answer1) != NULL) // check if the desired answer is in the response of the module
    		answer = 1;
    	else if ((expected_answer2 != NULL) && (strstr((char *)response, (const char *)expected_answer2) != NULL))
    		answer = 2;
    	else if (strstr((char *)response, "ERROR") != NULL)
    		answer = -1;
    
    	while ((answer == 0) && ((timeout--) != 0));
    	
    	if (display == 1)
    		printf("%s %s", ATcommand, response);
    	
    	if (buffer != NULL)
    		strcpy((char *)buffer, (char *)response);
    
    	return (answer);
    }
    *L'allocation de "uint8_t *response" de cette manière est temporaire !*

    Ta fonction readline() ne parait fausse. En effet, malgré son nom, elle ne lit pas une ligne entière. Elle lit 255 caractères. Et encore, comme on ne connait pas la fonction usart_read_buffer_wait(), on ne sait pas si c'est garanti de lire 255 caractères ou si c'est le maximum de caractères qui seront lus. De plus, le paramètre timeout n'est pas utilisé.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    uint8_t readline(uint16_t timeout)
    {
    	uint8_t buffer[255];
    
    	memset(&buffer, 0, 255);
    	usart_read_buffer_wait(&usart_instance_sim808, &buffer, 255);
    	printf(">%s<\r\n", buffer);
    	return (1);
    }
    Pour l'instant le return de cette fonction n'a aucun intérêt et celle-ci pourrai être un void, mais elle est destinée à évoluer.
    Effectivement on ne sait pas si c'est garanti de lire 255 cara, mais c'est 10x plus que toutes les réponses que j'ai pu obtenir de la SIM808. C'est donc une valeur arbitraire mise en place pour le dev. Il y a un /*FIXME*/ pour l'allocation de tous les buffers dans mon code.
    Je ne vois pas encore l’intérêt du paramètre timeout !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    enum status_code usart_write_wait(
    		struct usart_module *const module,
    		const uint16_t tx_data)
    {
    	/* Sanity check arguments */
    	Assert(module);
    	Assert(module->hw);
    
    	/* Get a pointer to the hardware module instance */
    	SercomUsart *const usart_hw = &(module->hw->USART);
    
    	/* Check that the transmitter is enabled */
    	if (!(module->transmitter_enabled)) {
    		return STATUS_ERR_DENIED;
    	}
    
    #if USART_CALLBACK_MODE == true
    	/* Check if the USART is busy doing asynchronous operation. */
    	if (module->remaining_tx_buffer_length > 0) {
    		return STATUS_BUSY;
    	}
    
    #else
    	/* Check if USART is ready for new data */
    	if (!(usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE)) {
    		/* Return error code */
    		return STATUS_BUSY;
    	}
    #endif
    
    	/* Wait until synchronization is complete */
    	_usart_wait_for_sync(module);
    
    	/* Write data to USART module */
    	usart_hw->DATA.reg = tx_data;
    
    	while (!(usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_TXC)) {
    		/* Wait until data is sent */
    	}
    
    	return STATUS_OK;
    }
    
    enum status_code usart_write_buffer_wait(
    		struct usart_module *const module,
    		const uint8_t *tx_data,
    		uint16_t length)
    {
    	/* Sanity check arguments */
    	Assert(module);
    	Assert(module->hw);
    
    	/* Check if the buffer length is valid */
    	if (length == 0) {
    		return STATUS_ERR_INVALID_ARG;
    	}
    
    	/* Check that the transmitter is enabled */
    	if (!(module->transmitter_enabled)) {
    		return STATUS_ERR_DENIED;
    	}
    
    	/* Get a pointer to the hardware module instance */
    	SercomUsart *const usart_hw = &(module->hw->USART);
    
    	/* Wait until synchronization is complete */
    	_usart_wait_for_sync(module);
    
    	uint16_t tx_pos = 0;
    
    	/* Blocks while buffer is being transferred */
    	while (length--) {
    		/* Wait for the USART to be ready for new data and abort
    		* operation if it doesn't get ready within the timeout*/
    		for (uint32_t i = 0; i <= USART_TIMEOUT; i++) {
    			if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE) {
    				break;
    			} else if (i == USART_TIMEOUT) {
    				return STATUS_ERR_TIMEOUT;
    			}
    		}
    
    		/* Data to send is at least 8 bits long */
    		uint16_t data_to_send = tx_data[tx_pos++];
    
    		/* Check if the character size exceeds 8 bit */
    		if (module->character_size == USART_CHARACTER_SIZE_9BIT) {
    			data_to_send |= (tx_data[tx_pos++] << 8);
    		}
    
    		/* Send the data through the USART module */
    		usart_write_wait(module, data_to_send);
    	}
    
    	/* Wait until Transmit is complete or timeout */
    	for (uint32_t i = 0; i <= USART_TIMEOUT; i++) {
    		if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) {
    			break;
    		} else if (i == USART_TIMEOUT) {
    			return STATUS_ERR_TIMEOUT;
    		}
    	}
    
    	return STATUS_OK;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    enum status_code usart_read_wait(
    		struct usart_module *const module,
    		uint16_t *const rx_data)
    {
    	/* Sanity check arguments */
    	Assert(module);
    	Assert(module->hw);
    
    	/* Error variable */
    	uint8_t error_code;
    
    	/* Get a pointer to the hardware module instance */
    	SercomUsart *const usart_hw = &(module->hw->USART);
    
    	/* Check that the receiver is enabled */
    	if (!(module->receiver_enabled)) {
    		//printf("ERR DENIED> ");
    		return STATUS_ERR_DENIED;
    	}
    
    #if USART_CALLBACK_MODE == true
    	/* Check if the USART is busy doing asynchronous operation. */
    	if (module->remaining_rx_buffer_length > 0) {
    		//printf(" BUSY> ");
    		return STATUS_BUSY;
    	}
    #endif
    
    	/* Check if USART has new data */
    	if (!(usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_RXC)) {
    		/* Return error code */
    		//printf(" BUSY> ");
    		return STATUS_BUSY;
    	}
    
    	/* Wait until synchronization is complete */
    	_usart_wait_for_sync(module);
    
    	/* Read out the status code and mask away all but the 3 LSBs*/
    	error_code = (uint8_t)(usart_hw->STATUS.reg & SERCOM_USART_STATUS_MASK);
    
    	/* Check if an error has occurred during the receiving */
    	if (error_code) {
    		/* Check which error occurred */
    		if (error_code & SERCOM_USART_STATUS_FERR) {
    			/* Clear flag by writing a 1 to it and
    			 * return with an error code */
    			usart_hw->STATUS.reg = SERCOM_USART_STATUS_FERR;
    			
    			//printf(" FORM> ");
    			return STATUS_ERR_BAD_FORMAT;
    		} else if (error_code & SERCOM_USART_STATUS_BUFOVF) {
    			/* Clear flag by writing a 1 to it and
    			 * return with an error code */
    			usart_hw->STATUS.reg = SERCOM_USART_STATUS_BUFOVF;
    
    			//printf(" OVERFLOW> ");
    			return STATUS_ERR_OVERFLOW;
    		} else if (error_code & SERCOM_USART_STATUS_PERR) {
    			/* Clear flag by writing a 1 to it and
    			 * return with an error code */
    			usart_hw->STATUS.reg = SERCOM_USART_STATUS_PERR;
    
    			//printf(" BAD DATA> ");
    			return STATUS_ERR_BAD_DATA;
    		}
    #ifdef FEATURE_USART_LIN_SLAVE
    		else if (error_code & SERCOM_USART_STATUS_ISF) {
    			/* Clear flag by writing 1 to it  and
    			 *  return with an error code */
    			usart_hw->STATUS.reg = SERCOM_USART_STATUS_ISF;
    
    			//printf(" PROTOCOL> ");
    			return STATUS_ERR_PROTOCOL;
    		}
    #endif
    #ifdef FEATURE_USART_COLLISION_DECTION
    		else if (error_code & SERCOM_USART_STATUS_COLL) {
    			/* Clear flag by writing 1 to it
    			 *  return with an error code */
    			usart_hw->STATUS.reg = SERCOM_USART_STATUS_COLL;
    
    			//printf(" COLLISION> ");
    			return STATUS_ERR_PACKET_COLLISION;
    		}
    #endif
    	}
    
    	/* Read data from USART module */
    	*rx_data = usart_hw->DATA.reg;
    
    	//printf(" OK |");
    	return STATUS_OK;
    }
    
    enum status_code usart_read_buffer_wait(
    		struct usart_module *const module,
    		uint8_t *rx_data,
    		uint16_t length)
    {
    	/* Sanity check arguments */
    	Assert(module);
    	Assert(module->hw);
    
    	/* Check if the buffer length is valid */
    	if (length == 0) {
    		//printf("INVALID ARG\r\n");
    		return STATUS_ERR_INVALID_ARG;
    	}
    
    	/* Check that the receiver is enabled */
    	if (!(module->receiver_enabled)) {
    		//printf("DENIED\r\n");
    		return STATUS_ERR_DENIED;
    	}
    
    	/* Get a pointer to the hardware module instance */
    	SercomUsart *const usart_hw = &(module->hw->USART);
    
    	uint16_t rx_pos = 0;
    
    	/* Blocks while buffer is being received */
    	while (length--) {
    		/* Wait for the USART to have new data and abort operation if it
    		 * doesn't get ready within the timeout*/
    		for (uint32_t i = 0; i <= USART_TIMEOUT; i++) {
    			if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_RXC) {
    				break;
    			} /*else if (i == USART_TIMEOUT) {
    				printf("STATUS ERR TIMEOUT\r\n");
    				return STATUS_ERR_TIMEOUT;
    			}*/
    		}
    
    		enum status_code retval;
    		uint16_t received_data = 0;
    
    		retval = usart_read_wait(module, &received_data);
    
    		if (retval != STATUS_OK) {
    			/* Overflow, abort */
    			//printf("PAS OK\r\n");
    			return retval;
    		}
    
    		/* Read value will be at least 8-bits long */
    		rx_data[rx_pos++] = received_data;
    
    		/* If 9-bit data, write next received byte to the buffer */
    		if (module->character_size == USART_CHARACTER_SIZE_9BIT) {
    			rx_data[rx_pos++] = (received_data >> 8);
    		}
    	}
    	//printf(" OK\r\n");
    	return STATUS_OK;
    }
    Merci !

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Si tu arrives à connecter directement ton PC à ton SIM808 avec une câble série, je te conseille de réussir à faire fonctionner tes commandes depuis ton terminal et ainsi ne pas utiliser plusieurs couches de code C potentiellement buggué / mal utilisé.

    C'est quoi un Edison ?

  6. #6
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 46
    Points : 11
    Points
    11
    Par défaut
    l'edison : https://software.intel.com/en-us/iot...e/discontinued
    En gros c'est un micro avec un proc ARM, de la RAM et ROM, et il est capable de faire tourner Linux.

    Si tu arrives à connecter directement ton PC à ton SIM808 avec une câble série, je te conseille de réussir à faire fonctionner tes commandes depuis ton terminal et ainsi ne pas utiliser plusieurs couches de code C potentiellement buggué / mal utilisé.
    Je suis connectée à l'edison, et c'est l'edison qui est connecté directement à la SIM808. Seulement il n'y a pas d'edison dans la version finale du projet, je suis donc obligé d'utiliser un code C. Depuis mon terminal avec l'edison tout fonctionne parfaitement, mais avec l’exécution du code en C (qui envoi exactement les mêmes commandes à la SIM808), j'obtiens un comportement différent de la SIM808 !

    Avec le code en C : Tout fonctionne parfaitement jusqu'au "AT+HTTPACTION" et "AT+HTTPREAD", qui me renvoi simplement "OK" en réponse.
    Avec le terminal en direct avec la SIM808 : Tout fonctionne parfaitement, réception et lecture de la réponse du serveur sans pb.

    Merci

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    OK c'est plus clair pour moi.

    Si le serveur reçoit et renvoie les bonnes trames, si l'utilisation du SIM808 fonctionne bien depuis le terminal de l'Edison, alors cela signifie que ton code C (celui que tu as écrit ou celui des bibliothèques que tu utilises).... est bogué

    As-tu moyen de sniffer la liaison physique entre le SIM808 et l'hôte du programme en C pour t'assurer que tu envoies et reçois la même chose ? Certains oscilloscopes peuvent le faire, mais la solution simple est sans doute un câble type UART to USB branché à l'hyperterminal de ton PC.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 46
    Points : 11
    Points
    11
    Par défaut
    Bonjour !
    Sniffer la communication aurait été trop long à mettre en place pour un résultat qui aurai été inutile.

    Le problème venait bien du code !

    Voici la fonction sendATcommand refaite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    int8_t sendATcommand(const uint8_t *ATcommand, const uint8_t *expected_answer1, const uint8_t *expected_answer2, int8_t *buffer, int line, uint8_t display)
    {
    	uint8_t answer = 0;
    
    	memset(rx_data, 0, 200);
    	
    	sendCommand(ATcommand, display);
    	readline(ATcommand, display);
    
    	if (strstr((char *)rx_data, (const char *)expected_answer1) != NULL) // check if the desired answer is in the response of the module
    		answer = 1;
    	else if ((expected_answer2 != NULL) && (strstr((char *)rx_data, (const char *)expected_answer2) != NULL))
    		answer = 2;
    	else if (strstr((char *)rx_data, "ERROR") != NULL)
    		answer = -1;
    	
    	if (buffer != NULL)
    		strcpy(buffer, rx_data);
    
    	return (answer);
    }
    
    uint16_t	readline(uint8_t *ATcommand, uint8_t display)
    {
    	uint16_t	temp, timeout = 50000;
    	uint16_t	rx_pos = 0;
    
    	while ((timeout > 0) && timeout--)
    	{
    		if (rx_pos >= 200)
    		break;
    		while (usart_read_wait(&usart_instance_sim808, &temp) == 0)
    		{
    			if (strstr(temp,"\r"))
    			continue;
    			if (temp == 0xA)
    			{
    				if (rx_pos == 0)
    				continue;
    			}
    			rx_data[rx_pos++] = temp;
    		}
    	}
    	
    	if ((display == 1) && (strstr(rx_data, ATcommand) != NULL))
    		puts(rx_data);
    	else if (display == 1)
    		puts(&rx_data[2]);
    	
    	return (rx_pos);
    }
    
    void	sendCommand(const uint8_t* ATcommand, uint8_t display)
    {
    	uint8_t	i = 0;
    	
    	if (display == 1)
    		printf("%s", ATcommand);
    	while (ATcommand[i] != '\0')
    	{
    		if (usart_write_wait(&usart_instance_sim808, ATcommand[i]) == 0)    // Send the AT command
    		i++;
    	}
    }
    rx_data est déclarer dans mon my.h (uint8_t rx_data[200]).

    As-tu quelque chose à redire sur mon code ? Des conseils ?

    Parfois la sim808 m'envoie ses réponses sous la forme "<CR><LF><response><CR><LF>", et parfois sous la forme "<commande><CR><LF><response><CR><LF>", une idée d'où cela peut venir ?

    J'arrive désormais à recevoir la réponse du serveur, mais la sim808 ne me répond toujours pas "+HTTPACTION:0,200,x", uniquement "OK", mais le AT+HTTPREAD fonctionne très bien derrière. Une idée là-dessus aussi ?

    Merci !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débuter] QTcpServer, serveur HTTP : récupérer les données POST
    Par zilators dans le forum Réseau
    Réponses: 0
    Dernier message: 24/08/2011, 14h11
  2. [WS 2003] Mise en place d'un serveur avec ssl/https
    Par titounnette dans le forum Windows Serveur
    Réponses: 10
    Dernier message: 15/10/2009, 13h48
  3. Réponses: 2
    Dernier message: 27/08/2009, 14h47
  4. [PayPal] Redirection HTTP sur serveur de paiement via method POST
    Par aphax dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 6
    Dernier message: 06/08/2009, 10h42
  5. [XML] Créer un fichier sur le serveur avec le contenu d'une requête POST
    Par kingmandrax dans le forum Bibliothèques et frameworks
    Réponses: 10
    Dernier message: 27/10/2006, 00h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo