Tuesday 28 August 2018

What is Kannel sms gateway ?

Kannel is an Opensource Software for SMS Gateway. I personally use this for sending SMS using HTTP and Short Message Peer-to-Peer(SMPP). A lot of readymade solutions are available using this as a backend. It has multiple channels/protocol supported for sending SMS.

Basic Concept of Kannel:
it will accept sms using one protocol and It may forward the same SMS using another protocol, So it is a kind of aggregator.
Different Modules  in this Project is
1. bearerbox
2. smsbox
3. wapbox
4. sqlbox(add-on)
5. opensmppbox(add-on)
6. pluginbox (external add-on)
7. ksmppd (external add-on)
8. smppbox (proprietary add-on)
9. playsms (opensource GUI)
The main module is bearerbox, which responsible for holding SMS channels(at modem, smpp, http, soap...etc) normally refers as SMS Center Connections. Handle Routing of SMS. Provide Feature of Retry. And Many more.

All Other boxes are kind of add-on they will make sms reach to bearerbox with added functionalities.

smsbox    --> will accept sms in http api and send dlr in http api and properly forward sms to bearerbox for delivery of sms. So you CRM/LMS/e-store can use smsbox to send sms irrespective of how your operator accepting request to send sms.

wapbox    ---> not explorer more, once i will explore definitely i will mention why to use wapbox

sqlbox     ----> want to store each SMS in Data Base so that later we can do billing, analytics, persistent queue, modification of content all these can be done using sqlbox, so I will say this is also an important module because performance analysis can be easier.

opensmppbox    ---> this will accept sms using Short Message Peer-to-Peer(SMPP) which has more demand in bulk SMS industry.

pluginbox     --> this is kind of interceptor and lot of custom logic can be developed using this like filter DND, Time Restriction, Spam filter, removing abusing words from SMS content, overriding sender id, prefixing sender/receiver. for more ...

ksmppd      --> It is smpp server like opensmppbox with added functionalities. for more ...

smppbox   --> This one proprietary smpp server with tons of customization.

playsms    --> GUI for kannel sms gateway. for more ...


So Summary is we can develop a full-fledged SMS gateway of our own using kannel open source software. Which will provide service for both MT SMS and MO SMS.


Tuesday 21 February 2017

Implement an itoa function


How do you implement an itoa function?

We can use below logic
1.divide Number by base and store the reminder in a buffer.
2.Change the Number with division result and repeat step 1 till Number become 1
3. reverse the buffer to have final result.


int my_itoa(int number, unsigned short base, char *output, size_t max_len){
        int length = 0;
        if(output == NULL || base > 36){
                return -1;
        }
        for( length=0; length < max_len; length++){
                char digit = number%base;
                if(digit<10){
                        digit += '0';
                }else{
                        digit += ('A'-10);
                }
                output[length] = digit;
                number = number/base;
                if(number==0){
                        break;
                }
        }

        if(length < max_len){
                my_strrev(output); // reverse buffer
        }else{
                return -1;
        }
        return length;
}

complete code


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int my_strrev(char *string){
        if(string == NULL){
                return 0;
        }
        int string_len = strlen(string);
        for(int left=0, right=string_len-1; left < right; left++, right--){
                char temp_ch = string[left];
                string[left] = string[right];
                string[right] = temp_ch;
        }
}

int my_itoa(int number, unsigned short base, char *output, size_t max_len){
        int length = 0;
        if(output == NULL || base > 36){
                return -1;
        }
        for( length=0; length < max_len; length++){
                char digit = number%base;
                if(digit < 10){
                        digit += '0';
                }else{
                        digit += ('A'-10);
                }
                output[length] = digit;
                number = number/base;
                if(number==0){
                        break;
                }
        }

        if(length < max_len){
                my_strrev(output);
        }else{
                return -1;
        }
        return length;
}

int main(int argc, char *argv[]){
        char buffer[256]={0x00};
        int number, base;
        for(int i=0; i < 10; i++){
                number = (rand()%1000)+1;
                base = (rand()%35)+1;
                memset(buffer, 0x00, sizeof(buffer));
                my_itoa(number, base, buffer, 256);
                printf("%d in Base %d =%s\n", number, base, buffer );
        }
        return 0;
}

Compile and Output


rajesh@ideapad:~/Rajesh/Blog/string$ gcc myitoa.c 
rajesh@ideapad:~/Rajesh/Blog/string$ ./a.out 
384 in Base 12 =280
778 in Base 6 =3334
794 in Base 11 =662
387 in Base 3 =112100
650 in Base 32 =KA
363 in Base 13 =21C
691 in Base 5 =10231
764 in Base 22 =1CG
541 in Base 2 =1000011101
173 in Base 17 =A3

Monday 20 February 2017

find circular linked list in c


How do you check whether a linked list is circular?

Most common algorithm is using "Floyd's Tortoise and hare" algorithm.

For More in Details

int list_find_cicular(node_p head){
        node_p fast = head;
        node_p slow = head;
        if(head == NULL || head->next == NULL){
                return 0;
        }
        do{
                if(fast->next->next){
                        fast = fast->next->next;
                        slow = slow->next;
                        if(slow == fast){
                                return 1;
                        }
                }else{
                        break;
                }
        }while(fast->next && slow->next);
        return 0;
}

Full Code


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

struct _node{
        void * data;
        struct _node* next;
};
typedef struct _node node_t;
typedef struct _node * node_p;

node_p new_list(void){
        node_p node= malloc(sizeof(node_t));
        assert(node!=NULL);
        node->data = NULL;
        node->next = NULL;
        return node;
}

node_p new_node(void *data){
        node_p node = malloc(sizeof(node_t));
        assert(node!=NULL);
        node->data = data;
        node->next = NULL;
        return node;
}

int list_free(node_p head){
        node_p iterator = head, temp;
        while(iterator){
                temp = iterator;
                iterator = iterator->next;
                free(temp);
        }
        return 0;
}
node_p list_tail(node_p head){
        node_p iterator = head;
        while(iterator->next != NULL){
                iterator = iterator->next;
        }
        return iterator;
}

node_p list_append(node_p head, void *data){
        node_p iterator = head;
        while(iterator->next != NULL){
                iterator = iterator->next;
        }
        iterator->next = new_node(data);
        return head;
}

node_p list_prepend(node_p head, void *data){
        node_p iterator = head;
        head = new_node(data);
        head->next = iterator;
        return head;
}

node_p list_for_each(node_p head, int (*func)(void *)){
        node_p iterator = head->next;
        while(iterator){
                func(iterator->data);
                iterator = iterator->next;
        }
}
int print_list_ele(void *data){
        if(data == NULL){
                return 0;
        }
        int number = *(int *)data;
        printf("%d\n", number);
        return 0;
}

int free_list_ele(void *data){
        if(data == NULL){
                return 0;
        }
        free(data);
        return 0;
}

int list_find_circular(node_p head){
        node_p fast = head;
        node_p slow = head;
        if(head == NULL || head->next == NULL){
                return 0;
        }
        do{
                if(fast->next->next){
                        fast = fast->next->next;
                        slow = slow->next;
                        if(slow == fast){
                                return 1;
                        }
                }else{
                        break;
                }
        }while(fast->next && slow->next);
        return 0;
}

int main(int argc, char *argv[]){
        if(argc < 2){
                fprintf(stderr, "USAGE: %s <numbers>\n", argv[0]);
                return -1;
        }
        node_p mylist = new_list();
        int *data = NULL;
        for(int i=1; i < argc; i++){
                data = malloc(sizeof(int));
                *data = atoi(argv[i]);
                list_append(mylist, data);
        }
        node_p mytail = list_tail(mylist);
        mytail->next = mylist; /*Making List Circular*/
        printf("List is %s\n", list_find_circular(mylist) ? "CIRCULAR":"NOT CIRCULAR");
        mytail->next = NULL; /* Removing Circular */
        list_for_each(mylist, print_list_ele);
        list_for_each(mylist, free_list_ele);
        list_free(mylist);
        return 0;
}

Compile and Output


rajesh@ideapad:~/Rajesh/Blog/single_linkedlist$ gcc list.c 
rajesh@ideapad:~/Rajesh/Blog/single_linkedlist$ ./a.out 10 20 30 40 50 60 70 80
List is CIRCULAR
10
20
30
40
50
60
70
80

Thursday 16 February 2017

number is in power series of 2


Write a Program to Find Given Number is in power series of 2 or Not?

Logic 1:
If Number Will keep on divide by 2 till the number become 1


int find_in_power_serise(int number, int power){
        do{
                if((number % power) ==0){
                        number = number/power;
                }else{
                        break;
                }
        }while(number > 1);
        if(number == 1){
                return 1;
        }else{
                return 0;
        }
}

Logic 2:
If we will see binary re-presentation of a Number.
we can come to know that if a single bit set then that number is in power series of 2.


int is_nth_bit_set(unsigned int num, int bit){
        return ((num >> bit) & 0x01);
}

int find_in_power_serise_of_2(unsigned int number){
        int count = 0;
        for(int i=0; i < (sizeof(number)*8) ; i++){
                if(is_nth_bit_set(number, i)){
                        count ++;
                }
        }
        if(count == 1){
                return 1;
        }else{
                return 0;
        }
}

without Loop and Without using % operator


int count_bit_set(unsigned int number, int count)
{
        if(number){
                if(number&0x01)
                        count++;
                return count_bit_set((number >> 1), count);
        }
        return count;
}

int find_in_power_serise_of_2_no_loop(unsigned int number){
        if(count_bit_set(number, 0)==1){
                return 1;
        }else{
                return 0;
        }
}

full code


#include <stdio.h>
#include <stdlib.h>

int find_in_power_serise(int number, int power){
        do{
                if((number % power) ==0){
                        number = number/power;
                }else{
                        break;
                }
        }while(number > 1);
        if(number == 1){
                return 1;
        }else{
                return 0;
        }
}

int is_nth_bit_set(unsigned int num, int bit){
        return ((num >> bit) & 0x01);
}

int find_in_power_serise_of_2(unsigned int number){
        int count = 0;
        for(int i=0; i < (sizeof(number)*8) ; i++){
                if(is_nth_bit_set(number, i)){
                        count ++;
                }
        }
        if(count == 1){
                return 1;
        }else{
                return 0;
        }
}

int count_bit_set(unsigned int number, int count)
{
        if(number){
                if(number&0x01)
                        count++;
                return count_bit_set((number >> 1), count);
        }
        return count;
}

int find_in_power_serise_of_2_no_loop(unsigned int number){
        if(count_bit_set(number, 0)==1){
                return 1;
        }else{
                return 0;
        }
}

int main(int argc, char *argv[]){
        if(argc != 2){
                fprintf(stderr, "USAGE:%s <number>\n", argv[0]);
                return -1;
        }
        int num = atoi(argv[1]);
        int power = 2;
        printf("%d is %s Power Serise of %d\n", num, find_in_power_serise(num, power)?"IN":"NOT IN", power);
        printf("%d is %s Power Serise of %d\n", num, find_in_power_serise_of_2(num)?"IN":"NOT IN", 2);
        printf("%d is %s Power Serise of %d\n", num, find_in_power_serise_of_2_no_loop(num)?"IN":"NOT IN", 2);
        return 0;
}

Compilation and Output


rajesh@ideapad:~/Rajesh/Blog/math$ gcc power_serise_2.c
rajesh@ideapad:~/Rajesh/Blog/math$ ./a.out 64
64 is IN Power Serise of 2
64 is IN Power Serise of 2
64 is IN Power Serise of 2
rajesh@ideapad:~/Rajesh/Blog/math$ ./a.out 65
65 is NOT IN Power Serise of 2
65 is NOT IN Power Serise of 2
65 is NOT IN Power Serise of 2

Wednesday 15 February 2017

Count the how many 7 are there between 1 to 100


Write a Program to Count How many times a digit is there in a range

There is a generic formula for this also n(10(n-1)) where range is 0 to 10n


/*one generic function to find char count in an string*/
unsigned int count_char_in_str(char ch, const char *str){
        unsigned int count=0;
        while((str=strchr(str, ch))!=NULL){
                count++;
                str+=1;
        }
        return count;
}
/*find single digit count in a series of numbers*/
unsigned int count_digit_in_range(unsigned int digit, unsigned int min , unsigned int max){
        char str_number[1024]={0x00};
        unsigned int count = 0;
        for(int i=min; i < max; i++){
                sprintf(str_number, "%02d", i);
                count += count_char_in_str(digit+0x30, str_number);
                memset(str_number, 0x00, sizeof(str_number));
        }
        return count;
}

Complete Code


#include <stdio.h>
#include <string.h>

unsigned int count_char_in_str(char ch, const char *str){
        unsigned int count=0;
        while((str=strchr(str, ch))!=NULL){
                count++;
                str+=1;
        }
        return count;
}
unsigned int count_digit_in_range(unsigned int digit, unsigned int min , unsigned int max){
        char str_number[1024]={0x00};
        unsigned int count = 0;
        for(int i=min; i <= max; i++){
                sprintf(str_number, "%d", i);
                count += count_char_in_str(digit+0x30, str_number);
                memset(str_number, 0x00, sizeof(str_number));
        }
        return count;
}

int main(int argc, char *argv[]){
        int number=7;
        int range_min = 1;
        int range_max = 100;
        printf("%d Times Number %d Coming between %d to %d\n", count_digit_in_range( number, range_min, range_max), number, range_min, range_max);
        return 0;
}

compile and output


rajesh@ideapad:~/Rajesh/Blog/string$ gcc cout_total_number_of_7_coming_serise.c
rajesh@ideapad:~/Rajesh/Blog/string$ ./a.out 
20 Times Number 7 Coming between 1 to 100