|Jobs| How can operators detect tethering?

出國玩,買 SIM卡 一定要注意,這張卡是否能夠當作 WiFi hotspot 分享給別人,

有的卡是不行的哦!!

在某次出差 (2017),我發現,電信業者是有能力知道這張 SIM卡是否有能力 WiFi hotspot,並且禁止這張卡做分享。

我一直以為是 framework 的行為(軟體端去擋),但是我做了一些實驗,發現電信商是可以控制的。(最近的新案子也有談到類似的東西)

表示在卡號之外,你這張卡是否有分享給別人,或者,
別支手機是否透過分享上網的,這兩個一定有其中一個資訊會被電信商知道。

稍微上網查了一下,電信商可以偵測到以下資訊,推斷出
你是否正在分享給別人/你是否是透過不能分享的網路上網

How can phone companies detect tethering (incl. Wifi hotspot)

  1. Your phone tells your network that you are tethering
  2. Inspecting the network packets for their TTL (time to live)
  3. MAC address inspection
  4. TCP/IP Stack Fingerprinting
  5. Looking at the Destination IP/URL

(補充)

電信商可以利用Tether Guard的機制來得知。基本上,你要用APN:dun建立連線才能 tethering給別人,

如果成功,表示電信商允許你分享!

特別是去英國或美國,要查一下你的卡哦!

Tethering on UK Networks: Which Mobile Networks Allow You To Tether?

|Jobs| ARM symposium 2019

This event intruduce three fields.
Kigen OS for Sim
Mbed OS for IoT device
Pelion for IoT devices management

For our OEM, I think we need to improve the knowledge of OS, compile tool chain, and debug tools.

We can start from the usage of objdump.

GDB and Objdump

|Jobs| 無線通訊裡的 NAS 是什麼 ?

之前工作主要是負責 NAS 相關的事項。

不過講 NAS 大家應該都會以為是儲存裝置。無線通訊裡面的 NAS 是 Non-Access Stratum 的縮寫,中文稱為:非接入層。

以下為 3GPP 網站寫的定義:

The Non-Access Stratum is a set of protocols in the Evolved Packet System. The NAS is used to convey non-radio signalling between the User Equipment (UE) and the Mobility Management Entity (MME) for an LTE/E-UTRAN access.

WIKI 的定義:

Non-access stratum (NAS) is a functional layer in the UMTS and LTE wireless telecom protocol stacks between the core network and user equipment.

一步步用簡單的語言理解:

  1. 一開機的時候,UE 會做掃網、選網及配置網路的工作。這些事是預備要讓你的裝置"接入到網路"。
  2. 認識接入層:RNC (Radio Network Controller:3G 基地台控制器,負責通話處理、網路管理等機制)、NodeB (3G 基地台) 需要參與處理的就是接入層。
  3. 當接入層處理完成、把橋搭好後,接下來就是非接入層的事。
  4. MM (Mobile Management)、CC (Call Control)、SMS (Short Message Service) 均為非接入層的業務。
  5. 再濃縮來講:接入層是比較靠基地台的行為,非接入層比較靠使用者服務的端的事。

(以上,如有理解錯誤,歡迎指正)

以 3GPP 來說,如果要理解 NAS,就要看懂 RRC 和 EMM 相關的 Spec 囉!

至於如果你在工作內容(JD)看到 NAS,基本上,凡事 Framework 要跟 Modem 溝通,牽涉到網路狀態相關行為的都要管啦~

Ref.

3GPP: http://www.3gpp.org/more/96-nas

WIKI: https://en.wikipedia.org/wiki/Non-access_stratum

博客: https://blog.csdn.net/starperfection/article/details/78737741

|Design| Communicate with Kernel driver

User space can not exchange data with kernel space directly.
They need to use system call.
e.g. fopen, ioctl, write, read …… etc.

In Kernel Space ……
1. Register your device with “register_chrdev”, defined in linux/fs.h .
 https://ithelp.ithome.com.tw/articles/10159749
2. Implement driver functions, ioctl, open,…
 struct file_operations fops = {
  .owner = THIS_MODULE,
  .read = device1_read,
  .write = device1_write,
  .ioctl = device1_ioctl,
  .open = device1_open,
  .release = device1_release,
 };

 int ioctl(struct inode *, struct file *, unsigned int, unsigned long);
 is in linux/ioctl.h
 http://ccckmit.wikidot.com/lk:io
 開發 driver 需要的基礎知識
 user space/kernel space 的IO觀念及實作

Copy data ……
 Kernel Space to User Space: copy_to_user()
 User Space to Kernel Space: copy_from_user()

In User Space ……
Use system call to control kernel driver.
 fopen (open)
 write
 read
 close
 seek
 poll / select
 ioctl
 mmap
 fcntl


e.g.

int main(int argc, char *argv[]){
  int devfd;
  int num = 0;

  if (argc > 1) num = atoi(argv[1]);
  if (num < 0) num = 0xff;

  devfd = open("/dev/debug", O_RDONLY);
  if (devfd == -1) {
    printf("Can't open /dev/debug\n");
    return -1;
  }

  printf("Write 0x%02x...\n", num);
  ioctl(devfd, IOCTL_WRITE, num);
  printf("Done. Wait 5 seconds...\n");
  sleep(5);
  close(devfd);

  return 0;
}

|Code| IPC methods

Originally, I though it is a basic interview question and everyone has at least a common answer .
Until I found someone did not know , I know I was wrong.

Threads can shares the same resources such as address space, file descriptors, stack and other process related attributes in the same process.
Processes can not share resources directly.

Processes will communicate to each other by IPC method.
There are two ways:
 1. Shared Memory
 2. Message passing

The following methods, which we often see, belong to message passing.
Pipe
Socket
Remote Procedural calls (RPCs)



https://www.geeksforgeeks.org/inter-process-communication-ipc/
https://stackoverflow.com/questions/200469/what-is-the-difference-between-a-process-and-a-thread

|Code| Makefile -I -L -l

e.g.
gcc -o hello hello.c -I /home/hello/include -L /home/hello/lib -lworld


Means:
-I /home/hello/include
Find headers in sequence of /home/hello/include–>/usr/include–>/usr/local/include

-L /home/hello/lib:
Find librarys in sequence of /home/hello/lib–>/lib–>/usr/lib–>/usr/local/lib

-lworld:
Find the library “libworld.so” in the path of “-L /home/hello/lib “

|Code| How to use control flow by pthread_cond_timedwait()

There are three parameters related with pthread_cond_timedwait().

Definition:
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);

Parameters:
pthread_cond_t *restrict cond : the condition you want to trigger this flow
pthread_mutex_t *restrict mutex : Mutual exclusion
const struct timespec *restrict abstime : absolutely waiting time ( = system time + waiting



【Step by Step】

Initial the mutex:
1. pthread_mutex_init(pthread_mutex_t *restrict  __mutex ,
              const pthread_mutexattr_t *restrict __mutex_attr);
   __mutex_attr can be NULL.
   __mutex_attr is the parameter about mutex.
  If it is not NULL, go to “2.”

2. pthread_mutexattr_init(pthread_mutexattr_t * __mutex_attr );
 pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
   type: PTHREAD_MUTEX_RECURSIVE,
      PTHREAD_MUTEX_NORMAL ……
3. pthread_cond_init(pthread_cond_t *restrict __cond ,
const pthread_condattr_t *restrict __cond_attr);

Start to wait for signal ” __cond “:
1. lock mutex: pthread_mutex_lock(&__mutex)
2. pthread_cond_timedwait(&__cond, &__mutex, &__abstime)
3. unlock mutex: pthread_mutex_unlock(&__mutex)

Start to send the signal ” __cond “:
1. lock mutex: pthread_mutex_lock(&__mutex)
2. pthread_cond_signal (&__cond)
3. unlock mutex: pthread_mutex_unlock(&__mutex)

Destroy the mutex:
1. pthread_mutex_destroy( pthread_mutex_t *restrict  __mutex );
2. pthread_mutexattr_destroy( pthread_mutexattr_t * __mutex_attr );
3. pthread_cond_destroy( pthread_cond_t *restrict __cond );

E.g.

// This thread will wait the signal.
void thread1(void *arg){
 int inArg = (int)arg;
 int ret = 0;
 struct timeval now;
 struct timespec outtime;

 pthread_mutex_lock(&g_mutex);

 gettimeofday(&now, NULL);
 outtime.tv_sec = now.tv_sec + 5;
 outtime.tv_nsec = now.tv_usec * 1000;
 ret = pthread_cond_timedwait(&g_cond, &g_mutex, &outtime);

 pthread_mutex_unlock(&g_mutex);
}


int main(void)
{
 pthread_t id1;
 int ret;

 // Initial mutex
 pthread_cond_init(&g_cond, NULL);
 pthread_mutex_init(&g_mutex, NULL);
 ret = pthread_create(&id1, NULL, (void *)thread1, (void *)1);

 if (0 != ret){
  printf(“thread 1 create failed!\n”);
  return 1;
 }

 printf(“Waiting %ds send the signal!\n”, SENDSIGTIME);
 sleep(SENDSIGTIME);

 // send the signal
 pthread_mutex_lock(&g_mutex);
 pthread_cond_signal(&g_cond);
 pthread_mutex_unlock(&g_mutex);
 pthread_join(id1, NULL);

 //Destroy the mutex
 pthread_cond_destroy(&g_cond);
 pthread_mutex_destroy(&g_mutex);
 return 0;
}

References:
https://blog.csdn.net/dead_g/article/details/73338960
https://linux.die.net/man/3/pthread_cond_timedwait
https://linux.die.net/man/3/pthread_cond_init
https://blog.csdn.net/yasi_xi/article/details/19112077

WordPress.com.

Up ↑