I'm trying to send some Hayes commands (AT commands) to my modem through a serial line.
The function I call is post_request::open(). Within this method there is a static commands string array holding the commands to configure the connection profile.
My first question is: Should I use a more "flexible" approach on creating the commands list?
I always need to send these eight commands to my modem. Of course the url, content_type and content_length vary.
Maybe somebody can show me a better way to do it.
int post_request::open(const char *url, unsigned content_length, const char *content_type)
{
static const char *commands[] =
{
// Connection profile
"AT^SISS=0,conId,0;",
// HTTP
"AT^SISS=0,srvType,Http;",
// User Agent
"AT^SISS=0,hcUsrAgent," USER_AGENT_STRING ";",
// HTTP method
"AT^SISS=0,hcMethod,1;",
// Placeholder for modem type bdx80
"AT;",
// Placeholder for address
"AT;",
// Placeholder for number of bytes sent
"AT;",
// Placeholder for content type
"AT;",
// Open internet session with configured profile
"AT^SISO=0\r",
NULL
};
// Some code...
if (modem->modem_type == bdx80)
commands[4] = "AT^SISS=0,secOpt,-1;";
// Some more code...
commands[6] = "AT^SISS=0,hcContLen,",content_length,";";
// Code for content_type settings...
int error = send_commands(modem, timeout, commands);
if (error)
return error;
}
After I finished the connection profile setup, I call send_commands().
I have a third party library which does the uart transmit & receive stuff.
The function I call within send_commands() is uart_tx().
Question: What do I need to do, to call uart_tx() correctly? I want the complete commands list to be sent at once.
Thx
static int
send_commands(modem_t *modem, unsigned timeout, const char *commands[])
{
// determine size of commands pointer array
unsigned len = ???;
// Send commands through serial line
if (uart_tx(modem->port, ???, &len, timeout))
return TIMEOUT;
}
/**
* Sends count bytes.
* #param port The serial port.
* #param buf[in] Pointer to the buffer containing the bytes to be sent.
* #param count[in,out] Pointer to the value containing the number of bytes to send
* (in) and the number of bytes actually sent (out).
* #param time_to_wait The maximum amount of time the task should block waiting
* for count bytes to be sent should the transmit queue be full at some time.
* #return 0 on successful transmission, 1 on timeout
*/
unsigned uart_tx(SerialPort port, const void *buf, unsigned *count, unsigned time_to_wait)
It seems like you want to just concatenate (memcpy or strcat or whatever) all the commands into a single buffer before sending them out.
Related
I'm working on USB CDC on ATSAMD21. The code which i'm using is ATMEL START example for USB CD Echo on D21. I'm working on atmel studio.
Requirement:
In my application the host send data to the device and i need to read that data and send back different data to the host from different function.
Here in echo example the data reception and transfer is using the call back. I'm not aware how to use a write call inside another function. Here i'm attaching the code below
Read & Echo the data:
Here in this function it is for read the data and echo it back to the host.
static bool usb_device_cb_state_c(usb_cdc_control_signal_t state)
{
if (state.rs232.DTR ) {
/* Callbacks must be registered after endpoint allocation */
cdcdf_acm_register_callback(CDCDF_ACM_CB_READ, (FUNC_PTR)usb_device_cb_bulk_out);
cdcdf_acm_register_callback(CDCDF_ACM_CB_WRITE, (FUNC_PTR)usb_device_cb_bulk_in);
/* Start Rx */
cdcdf_acm_read((uint8_t *)usbd_cdc_buffer, sizeof(usbd_cdc_buffer));
}
/* No error. */
return false;
}
/////////////////////////////////////
Read the data from host:
static bool usb_device_cb_bulk_out(const uint8_t ep, const enum
usb_xfer_code rc, const uint32_t count)
{
cdcdf_acm_write((uint8_t *)usbd_cdc_buffer, count);
return false;
}
Write back the data:
static bool usb_device_cb_bulk_in(const uint8_t ep, const enum usb_xfer_code rc, const uint32_t count)
{
/* Echo data. */
cdcdf_acm_read((uint8_t *)usbd_cdc_buffer, sizeof(usbd_cdc_buffer));
/* No error. */
return false;
}
I need to use this read call inside another function outside. I used the read call directly in another function, it was not able to send the data.
How can i make this call use in another function.Any help will be appreciated.
Here the callback will direct to the read and write functions.
This is a fun one!
From the main loop, using a stack allocated char buffer:
const char hello[] = "Hi There!\r\n";
cdcdf_acm_write((void*)hello, 11);
works for me, but curiously using a pointer to a string constant:
const char* hello = "Hi There!\r\n";
cdcdf_acm_write((void*)hello, 11);
does not output anything! Similarly, a static const buffer
const char hello[] = "Hi There!\r\n";
int main(void)
{
// init ...
while (1)
{
delay_ms(200);
cdcdf_acm_write((void*)hello, 11);
}
}
doesn't work either, but a non-const static buffer:
char hello[] = "Hi There!\r\n";
int main(void)
{
// init ...
while (1)
{
delay_ms(200);
cdcdf_acm_write((void*)hello, 11);
}
}
does!
My hypothesis is that cdcdf_acm_write() has a problem somewhere in the USB stack that cannot read data straight from flash, which seems like a very unexpected pitfall, especially as outputting a string constant is probably the first thing one does while implementing the communication functionality!
I am using openssl RSA algorithm to encrypt one file and send it to a server and then send it back with socket elements. But I can't get the original data. To be exactly, sometimes. I attach part of my code here, could you tell my why is it?
This is my code to encrypt and decrypt, I think it is not a problem:
int public_encrypt(unsigned char * data,int data_len, unsigned char *encrypted)
{
FILE *fp=fopen("public.pem","rb");
RSA *rsa;
rsa=PEM_read_RSA_PUBKEY(fp,NULL,NULL,NULL);
//RSA * rsa = createRSA(key,1);
int result = RSA_public_encrypt(data_len,data,encrypted,rsa,padding);
return result;
}
int private_decrypt(unsigned char * enc_data,int data_len, unsigned char *decrypted)
{
FILE *fp=fopen("private.pem","rb");
RSA *rsa;
rsa=PEM_read_RSAPrivateKey(fp,NULL,NULL,NULL);
//RSA * rsa = createRSA(key,0);
int result = RSA_private_decrypt(data_len,enc_data,decrypted,rsa,padding);
return result;
}
When sending something:
int encrypted_length=public_encrypt(buffer,st.st_size,publicKey,encrypted);
int decrypted_length= private_decrypt(encrypted,256,privateKey,decrypted);
The second line just to test if it can deccrypt well, and it works well all the time
When I am getting data from server, the code is:
int decrypted_length = private_decrypt(buffer,256,privateKey,decrypted);
The buffer is what I send. I used md5 to check the content, they are the same thing. After testing, the result in the private_decrypt is -1 in some case. The result is really unstable I can't find the reason. But I can find that if the file have already there, say I run this for second time with same functio, the result is not -1.
I tried to use ERR_get_error() to get the error, its result is 0x407106b, but I can't check this number anywhere.
I have function that reads the sensor data over I2C and fills that data in buffer.
void ADXLGetData(ADXLData_t * adxldataptr)
{
Buffer[0] = ADD_X0;
i2cRead(slave_add, reg_add,&buffer[0]);
adxldataptr->datax0 =buffer[1];
adxldataptr->datax1 = buffer[2];
adxldataptr->datay0 = buffer[3];
adxldataptr->datay1 = buffer[4];
adxldataptr->dataz0 = buffer[5];
adxldataptr->dataz1 = buffer[6];
}
where ADXLData_t is my structure of 6 bytes and buffer is declared as below in my header file.
volatile char buffer[12];
and other is like below.
char * ADXLGetData(void)
{
ADXLData_t *adxldataptr;
buffer[0] = ADD_X0;
i2cRead(slave_add, reg_add,&buffer[0]);
adxldataptr = (ADXLData_t*)&buffer[0];
return adxldataptr;
}
Both will be reading same sensor data. as i read data over timer interval of 1ms( that are four sensors including this) i am getting fault while using first function.
But if i use second function my program runs smooth.
In first function I get data perfectly over 5-6 iterations.
but in second I am not getting perfect data.
I am calling the functions as below.
for calling first function
ADXLData_t Acc1dataptr;
ADXLGetData(&Acc1dataptr);
for the second
ADXLData_t * Acc1dataptr;
Acc1dataptr = (ADXLData_t*) ADXLGetData();
This functions are called in another file not in same file , But I have included all the required files.
could please tell what i am doing wrong.?
This is more of a C programming question than a Bluetooth question.
I have a custom 128-bit UUID service containing an attribute with read/notify properties. The notify property is configured to send 20 bytes worth of data per notify packet. Currently, I am populating an array of 8-bit unsigned integers with 20 members using a for loop then sending it over the Bluetooth link.
This process takes about 1s which is far too slow (I am trying to maximize throughput). Is there a better way of moving 20 bytes other than in an array? I was able to achieve about 9k bit/s when I used just one uint64_t to hold the data but that only amounts to 8 bytes. My goal is to populate the full 20 byte capacity of the notify charateristic with the same speed.
My notify method is as follows: This fills in the value (val[]) to notify the client. It also sends a kernal message to the profile which then initiates a notification.
void app_sample128_set_char2_val(uint8_t* value)//(uint64_t value)
{
// Allocate the message
struct sample128_upd_char2_req * req = KE_MSG_ALLOC(SAMPLE128_UPD_CHAR2_REQ, TASK_SAMPLE128, TASK_APP, sample128_upd_char2_req);
// Fill in the parameter structure
req->conhdl = app_env.conhdl;
for (int x=0; x<20; x++)
{
req->val[x] = value[x];
}
ke_msg_send(req);
}
The characteristic update handler function is as follows: This function calls prf_server_send_event() which is responsible for sending notifications.
static int sample128_upd_char2_req_handler(ke_msg_id_t const msgid,
struct sample128_upd_char2_req const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
uint8_t status = PRF_ERR_OK;
// Check provided values
if(param->conhdl == gapc_get_conhdl(sample128_env.con_info.conidx))
{
// Update value in DB
attmdb_att_set_value(sample128_env.sample128_shdl + SAMPLE128_2_IDX_VAL,
20, (uint8_t *)¶m->val);
//maximum data value size for a notification attribute = 20 bytes
if((sample128_env.feature & PRF_CLI_START_NTF))
// Send notification through GATT
prf_server_send_event((prf_env_struct *)&sample128_env, false, sample128_env.sample128_shdl + SAMPLE128_2_IDX_VAL);
}
else
{
status = PRF_ERR_INVALID_PARAM;
}
if (status != PRF_ERR_OK)
{
sample128_upd_char2_cfm_send(status);
}
return (KE_MSG_CONSUMED);
}
So far I have gotten my libev code to successfully return a static sting that says "OMP OMP", however when I write a function that returns a "static" string it never seems to work. (Sidenote: the idea is to turn that same function into a dynamic response but just for agile testing purposes I need this to work first). My code for the libev read callback is as the following...
void p2pserver_network_buf_read_callback(struct bufferevent *incoming, void *arg){
//Define function local variables
struct evbuffer *evreturn;
char *req;
//Begin function local logic
req = evbuffer_readline(incoming->input);
if (req == NULL){
return;
}
char *response;
parse_json_command(req, response);
//response = "OMP OMP";
g_print("PARSED");
evreturn = evbuffer_new();
evbuffer_add_printf(evreturn, "%s", response);
bufferevent_write_buffer(incoming,evreturn);
evbuffer_free(evreturn);
free(req);
g_print("%s", response);
}
The parse_json_command function is as the following...
void parse_json_command(char json_command, char *response){
//Define Local Variables
g_print("PARSING");
response = "YOU KNOW";
//Print out the recieved message....
//g_message("%s", json_command);
/**
* TODO: check if the JSON is valid before parsing
* to prevent "Segmentation Defaults"
* and its good sanity checks.
**/
//Parse JSON incomming
/*json_object * jobj = json_tokener_parse(json_command);
enum json_type type;
json_object_object_foreach(jobj, key, val){
g_print("%s\n", key);
if(g_utf8_collate(key, "cmd") >= 0){
//Looks like the user has sent a "cmd" (command), lets analyze the "val" (value) of that command to see what the caller/client needs to be attending to...
//Is the client requesting an "Identity Update" (Pings server: if this is the first time ping, the server and client will exachange keys if the relationship exists the server just accepts the encrypted "ping" packet update)
type = json_object_get_type(val);
if(type == json_type_string){
char* cmd_value;
cmd_value = json_object_get_string(val);
//g_print("VALUE:%d\n", g_utf8_collate(cmd_value, "identupdate"));
if(g_utf8_collate(cmd_value, "identupdate") == 0){
//Call "Identity Update Response"
//char return_response = p2pserver_json_identupdate_response(json_command);
}
}
}
}
*/
return;
}
If you want to see the complete code (only a couple of pages big at the time of this writing) you can go to the source code at the following link: https://github.com/Xenland/P2PCrypt-Server
Thanks for your time and help!
c passes arguments by value, not by reference. You problem is here:
void parse_json_command(char json_command, char *response){
[...]
response = "YOU KNOW";
[...]
}
char *response;
parse_json_command(req, response);
response is a uninitialized pointer to a string. You are assigning a pointer to a static string to the response pointer in the function, but that does not modify response outside of the function, it just changes response within the function. There are different ways to fix this. Probably the easiest one for a quick fix would be to change the function's prototype to return a char * instead of void:
char * parse_json_command(char json_command){
char *response;
[...]
response = "YOU KNOW";
[...]
return response;
}
char *response;
response = parse_json_command(req);
Also, the json_command argument should probably be a char * or const char *, not just a single char, if you want to pass more than a single byte there.