Выделить на языке программирования C - PullRequest
0 голосов
/ 28 апреля 2018

Я использую XDK Bosch Sensor для проекта, который запрограммирован на C. Идея состоит в том, что XDK должен иметь возможность подключения к другой сети. SSID и пароль отправляются через MQTT. Уже возможно подключить XDK к сети при инициализации. Для получения сообщения MQTT используется функция, показанная ниже, которая была частично адаптирована Руководствами Bosch. Всякий раз, когда принимается сообщение MQTT, эта функция выполняется.

  • Цель: подключение к новой Wi-Fi-сети
  • Полученное сообщение выглядит всегда следующим образом: IP_Address/SSID/Password/ например. 192.155.125.146/TestSSID/TestPassword/

  • Уже протестировано: содержимое правильно получено самой функцией

  • Уже протестировано: CountNumberItemsPwd, CountNumberItemsSSID и CountNumberItemsIp правильно подсчитывают количество символов Pwd, SSID и IP-адреса

  • Использование printf для массивов arraySSID, arrayPW и arrayIp показывает правильное содержание

  • Предполагаемая проблема: Размер массивов символов, передаваемых в функцию, соединяющую XDK с новой сетью, похоже, требует правильного размера. Я пытался использовать негабаритные массивы символов безуспешно. Таким образом, я сейчас пытаюсь решить проблему с помощью alloc. К сожалению, я не могу заставить его работать и не могу найти, что я делаю неправильно с 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++;
            }
    

Я могу подключиться к новой сети, если в приведенной выше функции я использую следующий код вместо arraySSID и arrayPwd, хотя arraySSID и arrayPwd показывают то же содержимое, что и testSSID и testPW когда я печатаю оба на консоли.

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

Если я сравниваю arraySSID, arrayPwd и size из testSSID и testPwd, им выделяется другой размер. arraySSID, arrayPwd всегда имеют размер 4.

Для этого я использовал следующий код:

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

 printf("%d \n", sizeof(arrayPW));
 printf("%d \n", sizeof(testPW));

Ответы [ 2 ]

0 голосов
/ 28 апреля 2018

Проблема действительно была проблемой указателя .. Используя

   Retcode_T connect_rc3 = NetworkSetup(arraySSID, arrayPW);

функция работала отлично. Я не учел, что arrayPW уже имеет тип char *, так что &arraySSID имеет тип char **.

Я также изменил (IP <= CountNumberItemsIp) на (IP < CountNumberItemsIp).

0 голосов
/ 28 апреля 2018

Есть пара вопросов, на которые я хотел бы обратить внимание.

  • sizeof () в C - немного магическая функция. Он не печатает размер динамически распределенной памяти. Вместо этого вам лучше печатать CountNumberItemsSSID из вашего кода.
  • Другое дело, что в C вам нужны строки, заканчивающиеся нулем. Поэтому, когда вы подсчитываете байты таким образом и хотите, чтобы вывод был допустимой строкой, всегда допускайте 1 дополнительный символ и убедитесь, что это «\ 0».
  • Ваша логика заполнения, я уверен, что вы портите память, перезаписывая выделенную память для всех строк. Выделяя байты CountNumberItemsSSID для arraySSID, вы можете записывать только от 0 до (CountNumberItemsSSID-1), а не arraySSID [CountNumberItemsSSID], как это происходит в циклах while (). Они обязательно должны быть (SSID

Если вы исправите некоторые из многих проблем, я уверен, что это должно работать нормально.

...