-1

I am using the XDK Bosch Sensor for a project which is programmed in C. The idea is that the XDK should be able to connect to another network. SSID and password are sent via MQTT. It is already possible to connect the XDK to a network at initalization. In order to receive a MQTT message, the function shown below is used which was partly adapted by Guides of Bosch. Whenever a MQTT message is received this function is executed.

  • Aim: Connecting to new Wifi-network
  • The message I receive looks always as following: IP_Address/SSID/Password/ e.g. 192.155.125.146/TestSSID/TestPassword/

  • Already tested: The content is received correctly by the function itself

  • Already tested: CountNumberItemsPwd, CountNumberItemsSSID and CountNumberItemsIp count the number of characters of Pwd, SSID, and IP Address correctly

  • Using printf for the arrays arraySSID, arrayPW and arrayIp shows the correct content

  • Assumed Problem: The size of the char arrays, which are passed to the function connecting the XDK to a new network, seem to require to be sized properly. I tried to use oversized char arrays without success. Thus, I am currently trying to solve the problem with the help of alloc. Unfortunately, I cannot get it to work and cannot find what I am doing incorrectly with alloc.

            #define COMMON_BUFFER_SIZE 255
            char MQTT_BROKER_HOST[] =   "192.111.111.111";
            char message_received [COMMON_BUFFER_SIZE];
    
    
            /**
             * @brief Event handler for incoming publish MQTT data
             *
             * @param[in] publishData
             * Event Data for publish
             */
            static void HandleEventIncomingPublish(
                    MqttPublishData_T publishData)
            {
                char published_topic_buffer[COMMON_BUFFER_SIZE];
                char published_data_buffer[COMMON_BUFFER_SIZE];
                static int incoming_message_count = 0;
    
                //storing topic and incoming data
                strncpy(published_data_buffer, (const char *)publishData.payload, sizeof(published_data_buffer));
                strncpy(published_topic_buffer, publishData.topic.start, sizeof(published_topic_buffer));
    
    
                //If the message differs from the one received before, connect to new network
                if (message_received != published_data_buffer)
                {
                    //Store message in message_received
                    strcpy(message_sent, published_data_buffer);
    
                    //For While-Loop
                    int counterForArray = 0;
    
                    //For writing content into correct arrays
                    int BooleanForIP = 0;
                    int BooleanForPw = 0;
                    int BooleanForSSID = 0;
    
                    int CountCycles = 0; //For Array Access
    
                    //Counting of how many items IP Address,  SSID and Password consist of
                    int CountNumberItemsIp = 0;
                    int CountNumberItemsPW = 0;
                    int CountNumberItemsSSID = 0;
    
                    //Buffer Arrays
                    char IP_new[20] = "";
                    char PW_new[50] = "";
                    char SSID_new[25] = "";
    
    
                    while (counterForArray < COMMON_BUFFER_SIZE)
                    {
                            //Check if IP Address has been successfully received
                            if (message_received[counterForArray] == '/' && BooleanForIP == 0 && BooleanForSSID == 0 && BooleanForPw == 0)
                            {
                                BooleanForIP = 1;
                                CountNumberItemsIp = CountCycles;
                                CountCycles = 0;
    
                            }
                             //Checking if SSID has been successfully received
                            else if (message_received[counterForArray] == '/' && BooleanForIP == 1 && BooleanForSSID == 0 && BooleanForPw == 0)
                            {
    
                                BooleanForSSID = 1;
                                CountNumberItemsSSID  = CountCycles;
                                CountCycles = 0;
    
                                printf("Stage 2 reached \n");
                            }
    
                            //Checking if Password has been successfully received
                            else if (message_received[counterForArray] == '/' && BooleanForIP == 1 && BooleanForSSID == 1 && BooleanForPw == 0)
                                {
                                    BooleanForPw = 1;
                                    CountNumberItemsPW = CountCycles;
                                    CountCycles = 0;
                               }
    
    
    
                            if (BooleanForIP == 0 && BooleanForPw == 0 && BooleanForSSID == 0)
                            {
                                IP_new[CountCycles] = message_received[counterForArray];
                                       CountCycles = CountCycles + 1;
                            }
    
                            else if (BooleanForIP == 1 && BooleanForPw == 0 && BooleanForSSID == 0 && message_received[counterForArray] != '/')
                            {
                                SSID_new[CountCycles] = message_received[counterForArray];
                                    CountCycles = CountCycles + 1;
                            }
    
                            else if (BooleanForIP == 1 && BooleanForPw == 0 && BooleanForSSID == 1 && message_received[counterForArray] != '/')
                                {
                                    PW_new[CountCycles] = message_received[counterForArray];
                                    CountCycles = CountCycles + 1;
                               }
    
                        counterForArray = counterForArray + 1;
                    }
    
                    //Dynamic memory
                    char *arraySSID;
                                    arraySSID = (char*)calloc(CountNumberItemsSSID, sizeof(char));
    
                     char *arrayIP;
                    arrayIP = (char*)calloc(CountNumberItemsIp, sizeof(char));
    
                             char *arrayPW;
                            arrayPW = (char*)calloc(CountNumberItemsPW, sizeof(char));
    
                            //Copying content
    
            int SSID = 0;
            while (SSID <= CountNumberItemsSSID)
            {
                arraySSID[SSID] = SSID_new[SSID];
                SSID = SSID + 1;
            }
    
            int PW = 0;
    
            while (PW <= CountNumberItemsPW)
            {
                arrayPW[PW] = PW_new[PW];
                PW = PW + 1;
            }
    
            int IP = 0;
            while (IP <= CountNumberItemsIp)
           {
                   arrayIP[IP] = IP_new[IP];
                   IP = IP + 1;
           }
    
                    //Disconnecting from old Wifi
                    //Functions provided by Bosch
    
                    Retcode_T retStatusDisconnect = (Retcode_T) WlanConnect_Disconnect(0);
                    retcode_t DisconnectMQTT = Disconnect();
    
                    Retcode_T connect_rc3 = NetworkSetup(&arraySSID, &arrayPW);
                    if (connect_rc3 ==  RETCODE_OK)
                    {
    
                        printf("success \n");
    
                    }
    
                    else
                    {
                        Retcode_RaiseError(connect_rc3);
    
                    }
    
    
                    //Checking if content has been sent correctly 
                    printf("%s :arraySSID \n",arraySSID);
                    printf("%s :arrayPW \n",arrayPW);
                    printf("%s :arrayIP \n",arrayIP);
                    printf("%s: SSID \n", SSID_new);
                    printf("%s: IP \n", IP_new);
                    printf("%s: PW \n", PW_new);
                    //Deallocate space
    
                    free(arraySSID);
                    free(arrayPW);
                    free(arrayIP);
                }
    
                //Print received message
                printf("%s \n", message_received);
    
                incoming_message_count++;
            }
    

I am able to connect to a new network if I use following code in the function above instead of the arraySSID and arrayPwd even though arraySSID and arrayPwdshow the same content as testSSID and testPW when I print both on the console.

 char testSSID[] = "TestSSID";
 char testPW[] = "TestPwsd";
 Retcode_T connect_rc3 = NetworkSetup(&testSSID, &testPW);

If I compare arraySSID, arrayPwd and the size of testSSIDand testPwd, a different size is allocated to them. arraySSID, arrayPwd are always of size 4.

For doing so, I used following code:

 printf("%i \n", sizeof(arraySSID));
 printf("%i \n", sizeof(testSSID));

 printf("%d \n", sizeof(arrayPW));
 printf("%d \n", sizeof(testPW));
JayJay
  • 43
  • 2
  • 13
  • When you pass e.g. `&testPW` you pass a pointer to the array. Its type is `char (*)[9]` (with the example password you show). That is most likely not what the function you call expect, I'm sure it expects something of type `char *`. Which you get by passing a pointer to the first element, as in `&testPW[0]`, or just plain `testPW` (arrays naturally decay to a pointer to their first element). – Some programmer dude Apr 28 '18 at 14:55
  • 1
    Furthermore, getting the size of a pointer returns the size of the pointer itself, not what it points to. – Some programmer dude Apr 28 '18 at 14:55
  • Lastly, remember to only call `free` on memory you have received from `malloc`. – Some programmer dude Apr 28 '18 at 14:56
  • 1
    Oh one more thing, if you have something like `arrayPW` which already is of type `char *`, then doing `&arrayPW` gets you a pointer *to the variable*, and it's of type `char **`. – Some programmer dude Apr 28 '18 at 14:58
  • to print `sizeof` results [use `%zu`](https://stackoverflow.com/q/940087/995714), not any other format specifiers – phuclv Apr 28 '18 at 15:06
  • `if (message_received != published_data_buffer)` you are comparing two address constants here. – wildplasser Apr 28 '18 at 15:19
  • You are right with comparing two adresses. I might be better of using something like `strcmp`. – JayJay Apr 28 '18 at 15:31
  • Since you seem to be very fond of `strncpy()`, I'd suggest using `memcmp()` instead. – wildplasser Apr 28 '18 at 15:36

2 Answers2

1

There are a couple of issues that I would like to point.

  • sizeof() in C is a bit of a magic function. It does not print the size of dynamically allocated memory. Instead you would be better off with printing CountNumberItemsSSID from your code.
  • The other thing is that, in C you need strings to be null-terminated. So, when you counting bytes in this way and if you want the output to be a valid string, always allow for 1 extra character and make sure that is '\0'.
  • Your filling logic, I am positive that you are corrupting memory by writing over the allocated memory for all strings. By allocating CountNumberItemsSSID bytes for arraySSID, you can only write from 0 upto (CountNumberItemsSSID-1), not arraySSID[CountNumberItemsSSID] as you are doing in your while() loops. They should definitely be (SSID < CountNumberItemsSSID).

If you fix some of the many issues, I am sure it should just work fine.

0

The problem was indeed a pointer problem.. By using

   Retcode_T connect_rc3 = NetworkSetup(arraySSID, arrayPW);

the function worked perfectly fine. I did not consider that arrayPW is already of type char *, so that &arraySSID is of type char **.

I also changed (IP <= CountNumberItemsIp) to (IP < CountNumberItemsIp).

JayJay
  • 43
  • 2
  • 13